C# 在DLL中使用默认关键字

C# 在DLL中使用默认关键字,c#,mono,default,C#,Mono,Default,在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;

在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;
    }
}
我使用ILSpy查看DLL并注意到:

public class BaseClass<T>
{
    public T value;
    public bool enabled;
    public BaseClass(T value = null, bool enabled = true)
    {
        this.value = value;
        this.enabled = enabled;
    }
}
公共类基类
{
公共价值观;
公共布尔启用;
公共基类(T值=null,bool enabled=true)
{
这个值=值;
this.enabled=已启用;
}
}
请注意,构造函数中的
default
已替换为
null
。这似乎是问题的原因,因为null对于值类型是无效的值

这是怎么回事


编辑:正如在评论中发现的那样,当第二个项目使用VS2013或更新版本的Mono编译时,不会出现这种情况。

这似乎是Mono编译器3.2.3之前版本的一个错误(@usr在最初的评论中是非常正确的)。编译器将默认参数值作为属性插入程序集元数据(请参见)。我验证了ilspy的输出与ildasm一致,后者将
默认值(T)
编码为
。参数[1]=nullref
。我怀疑约定是泛型
default(T)
被编码为null,而消费编译器应该知道如何使用它。但是,从日期来看,这似乎与此有关,这个特定问题在报告之前的某个时间已经修复。

这是一个编译器错误。它是什么编译器?我刚刚在VS 2013上试用过,效果很好。在VS 2012的.NET 4.0上测试,编译为X86-效果很好。DLL是用VS创建的,但使用它的项目使用的是Mono。我刚刚用VS项目进行了测试,效果很好。问题是,是Mono还是VS错了?VS正在将
default(T)
编译为
null
,但在使用DLL时仍将其视为
default(T)
。Mono似乎在使用
null
,因为实际上就是这样。也许VS实际上并没有编译为null,而是编译为“默认”。也许工具只是以错误的方式显示了这一点。您可以查看CLS规范中程序集元数据实际能够存储的内容。
public class OtherClass
{
    public BaseClass<int> baseInt;
}
public class BaseClass<T>
{
    public T value;
    public bool enabled;
    public BaseClass(T value = null, bool enabled = true)
    {
        this.value = value;
        this.enabled = enabled;
    }
}