在DLL项目中使用default
关键字时,我遇到了一个非常奇怪的问题。在我的DLL项目(用VS2013编译)中,我有以下类:
public class BaseClass<T>
{
public T value;
public bool enabled;
public BaseClass ( T value = default(T), bool enabled = true )
{
this.value = value;
this.enabled = enabled;
}
}
现在,如果我在DLL项目中使用它,它可以完美地工作。我可以毫无问题地创建从这个基类派生的类。但是,当我试图在另一个项目(用Mono 2.0.0编译)中使用DLL时,从具有值类型的基类派生会导致编译器错误。这一点:
public class ChildClass : BaseClass<int>
{
}
导致此问题的原因:
Assets/ChildClass.cs(8,14):错误CS1502: BaseClass.BaseClass(int,bool)的最佳重载方法匹配具有一些无效参数
Assets/ChildClass.cs(8,14):错误表达式:参数#1' cannot convert
null‘CS1503 to type’`int‘
但是,可以在字段中使用具有值类型的基类,这是没有问题的:
public class OtherClass
{
public BaseClass<int> baseInt;
}
我使用ILSpy查看了动态链接库,并注意到:
public class BaseClass<T>
{
public T value;
public bool enabled;
public BaseClass(T value = null, bool enabled = true)
{
this.value = value;
this.enabled = enabled;
}
}
请注意,构造函数中的default<T>
已替换为null
。这似乎是问题的原因,因为对于值类型来说,null可能是无效值。
那么这是怎么回事呢?
编辑:正如在评论中发现的,当第二个项目是用VS2013或更新版本的Mono编译时,不会发生这种情况。
发布于 2014-11-06 03:31:34
这似乎是mono编译器3.2.3之前版本的一个bug (@usr在他们最初的评论中是非常正确的)。编译器将默认参数值作为属性插入到程序集元数据中(请参见this answer)。我验证了ilspy的输出与将default(T)
编码为.param [1] = nullref
的ildasm一致。我怀疑惯例是泛型default(T)
被编码为null,消费编译器应该知道如何使用它。它似乎与this issue有关,然而,根据日期,这个特定的问题在报告之前一段时间就被修复了。
https://stackoverflow.com/questions/26763434
复制相似问题