【问题标题】:Constructor with optional parameter violates new() constraint具有可选参数的构造函数违反 new() 约束
【发布时间】:2014-04-30 14:08:38
【问题描述】:
我有一个带有这个构造函数的类:
public Currency(Guid? vcurrencyUI = null)
: base(vcurrencyUI)
{ }
并且我想使用带有new() 约束的此类,但我收到此错误:
'Currency' 必须是具有公共无参数构造函数的非抽象类型,以便在泛型类型或方法中将其用作参数'T' ...
如果我拆分构造函数一切正常:
public Currency(Guid? vcurrencyUI)
: base(vcurrencyUI)
{ }
public Currency()
: base()
{ }
为什么要拆分构造函数?
【问题讨论】:
标签:
c#
generics
constructor
constraints
【解决方案1】:
尽管 Jim already answered 你的问题,请注意,更通用的方法可能是允许传递一个 delegate 来实例化你的具体类,而不是强制你的所有实现都是无参数的。 p>
即而不是这个:
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);
}
}
【解决方案2】:
因为带默认参数的构造函数不是无参数构造函数。
默认参数由编译器在编译时“填充”。当你写:
var foo = new Currency();
编译器生成:
var foo = new Currency(null);
当类被编译时,编译器会创建一个构造函数来接受 Guid? 参数,并生成一些元数据,实际上是“如果在编译时未提供参数,则提供 null”。但是没有为该类型生成无参构造函数。
new() 约束要求为该类型定义无参数构造函数,并且它不接受具有单个默认参数的构造函数。这很可能是因为运行时(最终不得不调用构造函数)不理解默认参数的概念。