2014-11-05 105 views
17

在DLL项目中使用default关键字时,我遇到了一个非常奇怪的问题。在我的DLL项目(与VS2013编译)我有下面的类:在DLL中使用默认关键字

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的项目中,它完美的作品。我可以创建从这个基类派生出来的类,而没有问题。但是,只要我尝试在另一个项目中使用DLL(用Mono 2.0.0编译),则从基类派生一个值类型会导致编译器错误。此:

public class ChildClass : BaseClass<int> 
{ 
} 

原因此:

资产/ ChildClass.cs(8,14):错误CS1502:该用于BaseClass的< int>的.BaseClass最佳重载方法匹配(INT,布尔)”有一些无效参数

资产/ ChildClass.cs(8,14):错误CS1503:参数#1' cannot convert空 '表达键入`INT'

Howev呃,值类型的基类可以在字段中使用没有问题:

public class OtherClass 
{ 
    public BaseClass<int> baseInt; 
} 

我看着使用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; 
    } 
} 

注意default<T>在构造函数中已经换成null。这似乎是问题的原因,因为null对于值类型是无效值。

那么这里发生了什么?

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

+1

这是一个编译器错误。它是什么编译器? – usr 2014-11-05 17:37:25

+0

Visual Studio 2013 – Adam 2014-11-05 17:43:58

+1

我刚刚与VS 2013一起尝试过,它工作正常。 – 2014-11-05 17:44:39

回答

4

这似乎是单声道编译器3.2.3之前的错误(@usr在他们的初始评论中是非常正确的)。编译器将默认参数值作为属性插入到程序集元数据中(请参阅this answer)。我验证了ilspy的输出与编码default(T).param [1] = nullref的ildasm一致。我怀疑这个约定是,一个通用的default(T)被编码为空,而编译器只是应该知道如何使用它。它似乎与this issue有关,但是,根据日期,这个特定问题在报告之前的某个时间是固定的。