如何使用new关键字创建泛型类?附AlarmSeverityDto类实现及使用示例
如何用
new关键字创建泛型类实例 嘿,看起来你已经在使用泛型集合(比如List<AlarmSeverityDto>)管理你的数据传输对象了,现在想搞清楚怎么用new关键字创建泛型类的实例对吧?结合你的AlarmSeverityDto代码场景,我来给你一步步拆解:
1. 基础:泛型的new()约束
如果你想在泛型方法或类里直接用new创建泛型类型的实例,首先得给泛型参数加上new()约束——这相当于告诉编译器:这个泛型类型必须有一个无参构造函数。
举个简单的通用创建方法例子:
public T CreateDto<T>() where T : new() { return new T(); }
但回到你的场景,AlarmSeverityDto只有带DataRow参数的构造函数,直接用new()约束肯定行不通,那该怎么适配?
2. 适配你的AlarmSeverityDto:带参数的泛型实例创建
因为你的Dto需要依赖DataRow初始化,这里有两种实用的实现方式:
方式一:接口规范+泛型约束(类型安全,更优雅)
首先定义一个接口,统一规定Dto的初始化逻辑:
public interface IDataRowInitializable { void Initialize(DataRow dr); }
然后修改你的AlarmSeverityDto,实现这个接口,并添加一个无参构造函数(满足泛型约束要求):
public class AlarmSeverityDto : IDataRowInitializable { private DataRow _dr; // 添加无参构造,用于泛型创建 public AlarmSeverityDto() { } public object this[string columnname] => _dr[columnname]; public string Id => Convert.ToString(_dr["Id"]); public string Description => Convert.ToString(_dr["Description"]); // 保留原有带参构造,兼容旧代码 public AlarmSeverityDto(DataRow dr) { _dr = dr; } // 实现接口的初始化方法 public void Initialize(DataRow dr) { _dr = dr; } }
接下来写一个通用的泛型创建方法,用new()创建实例后再执行初始化:
public T CreateDtoFromRow<T>(DataRow dr) where T : IDataRowInitializable, new() { var dto = new T(); dto.Initialize(dr); return dto; }
这样你在GetAlarmSeverityDtos里就能这么用了:
public List<AlarmSeverityDto> GetAlarmSeverityDtos() { var resultList = new List<AlarmSeverityDto>(); // 假设你从数据库拿到了DataTable dt foreach(DataRow dr in dt.Rows) { var dto = CreateDtoFromRow<AlarmSeverityDto>(dr); resultList.Add(dto); } return resultList; }
方式二:用Activator.CreateInstance(无需修改原有Dto)
如果你不想改动现有的AlarmSeverityDto代码,可以用反射的方式通过带参数的构造函数创建泛型实例:
public T CreateDtoFromRow<T>(DataRow dr) { // 传入构造参数,反射创建泛型实例 return (T)Activator.CreateInstance(typeof(T), dr); }
这个方法不需要给T加任何约束,直接调用目标类型的带参构造,在你的方法里使用方式和上面完全一致。
3. 额外优化:批量转泛型列表
如果你经常需要把DataTable转换成Dto列表,可以写一个扩展方法简化操作:
public static List<T> ToDtoList<T>(this DataTable dt) where T : IDataRowInitializable, new() { var dtoList = new List<T>(); foreach(DataRow dr in dt.Rows) { var dto = new T(); dto.Initialize(dr); dtoList.Add(dto); } return dtoList; }
这样你的GetAlarmSeverityDtos就能简化成一行代码:
public List<AlarmSeverityDto> GetAlarmSeverityDtos() { // 假设dt是你的DataTable return dt.ToDtoList<AlarmSeverityDto>(); }
最后总结一下:
- 当泛型类型有无参构造函数时,用
new()约束+new T()直接创建 - 当需要带参数构造时,要么通过接口规范后续初始化,要么用
Activator.CreateInstance反射创建
内容的提问来源于stack exchange,提问作者user1436795
相关产品推荐
相关产品推荐

