如何使方法的返回OBJECT通用?

时间:2017-07-28 10:02:57

标签: c# .net generics return-type

我需要像下面的代码那样做,但新的T()不起作用。它说 “无法创建变量类型T的实例,因为它没有new()约束。”

public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown
{
    return new T() //FAILS
    {
        Id = dd.Id,
        Description = dd.Description
    };
}

BaseDropDown是3个子节点的基类,这些子节点是使用EntityFramework(代码优先)映射的实体,因此最好保持尽可能简单。

现在它不是抽象的,因为我尝试了一些实现,但如果可能的话,它将是。

public class BaseDropDown
{
    public int Id { get; set; }
    public string Description { get; set; }
}

4 个答案:

答案 0 :(得分:2)

调用new T()假设每个类型都有一个无参数构造函数,这似乎不是这里的情况。即使您的基类BaseDropDown具有这样的构造函数,也不保证其所有子类,特别是抽象的子类:

class BaseDropDown
{
    public BaseDropDown() { /* see parameterless-constructor exists */ }
}
abstract class MyClass : BaseDropDown
{
    public MyClass() { ... }
}

现在您可以使用new - 约束来排除抽象类:

public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown, new()

该约束将允许onlx允许继承BaseDropDown 的类使用无参数构造函数进行实例化。

答案 1 :(得分:2)

这也有效,只需将new()约束直接添加到T(而不是BaseDropDown)

public static T MapToBaseDropDown3<T>(this GenericDropDownData dd) where T : BaseDropDown, new()
{
    return new T()
    {
        Id = dd.Id,
        Description = dd.Description
    };
}

答案 2 :(得分:1)

BaseDropDown类需要像这样应用new()约束:

public class BaseDropDown<T> where T : SomeClass, new()
{
}

new()约束必须始终最后应用。有关详细信息,请参阅here

答案 3 :(得分:-1)

使用反射工作正常:

public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown
{
    T entityDd = (T)Activator.CreateInstance(typeof(T));
    entityDd.Id = dd.Id;
    entityDd.Description = dd.Description;
    return entityDd;
}