You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:34:34