我有一个带有这个构造函数的类:
public Currency(Guid? vcurrencyUI = null)
: base(vcurrencyUI)
{ }
我希望将此类与new()
约束一起使用,但我收到此错误:
'Currency'必须是具有公共无参数构造函数的非抽象类型,才能在泛型类型或方法中将其用作参数'T'...
如果我拆分构造函数,一切正常:
public Currency(Guid? vcurrencyUI)
: base(vcurrencyUI)
{ }
public Currency()
: base()
{ }
为什么我需要拆分构造函数?
答案 0 :(得分:15)
因为具有默认参数的构造函数不是无参数构造函数。
默认参数"填写"由编译器在编译时。当你写:
var foo = new Currency();
编译器生成:
var foo = new Currency(null);
编译类时,编译器会创建一个构造函数,该构造函数接受Guid?
参数,并生成一些有效的元数据"如果参数在编译时未提供,然后提供null
。"但是没有为该类型生成无参数构造函数。
new()
约束要求为该类型定义无参数构造函数,并且它不会接受具有单个默认参数的构造函数。很可能是因为运行时最终不得不调用构造函数,因此不了解默认参数的概念。
答案 1 :(得分:5)
虽然Jim already answered是您的问题,但请注意,更通用的方法可能是允许传递委托,这将实例化您的具体类,而不是强制所有实现都是无参数的。
即。而不是这个:
public class Something<T> where T : new()
{
public T CreateInstance()
{
return new T();
}
}
您可以传递一个显式委托,它将执行任何自定义实例化逻辑:
// note that the constraint is now removed
public class Something<T>
{
private readonly Func<T> _ctor;
public Something(Func<T> ctor)
{
_ctor = ctor;
}
public T CreateInstance()
{
return _ctor();
}
}
// and you can now pass arbitrary constructor logic as a delegate
var x = new Something<Currency>( () => new Currency(null) );
这也允许您创建一个帮助程序类,并且可以随时使用这两个选项:
public class Something
{
// this allows you to use a parameterless ctor
public static Something<T> Create<T>() where T : new()
{
return new Something<T>(() => new T());
}
// this allows you to specify a custom one
public static Something<T> Create<T>(Func<T> ctor)
{
return new Something<T>(ctor);
}
}