2014-11-05 44 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有關,但是,根據日期,這個特定問題在報告之前的某個時間是固定的。