我需要像下面的代码那样做,但新的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; }
}
答案 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;
}