2014-11-05 15 views
17

Wystąpił naprawdę dziwny problem podczas używania słowa kluczowego default w projekcie DLL. W moim projekcie DLL (skompilowany z VS2013) Mam następujące klasy:Używanie domyślnego słowa kluczowego w bibliotece 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; 
    } 
} 

Teraz, jeśli mogę użyć tego środka projektu DLL, to działa doskonale. Mogę tworzyć klasy wywodzące się z tej klasy bazowej bez problemu. Ale, gdy tylko spróbuję użyć biblioteki DLL w innym projekcie (skompilowanym z Mono 2.0.0), wyprowadzenie z klasy bazowej z typem wartości powoduje błąd kompilatora. To:

public class ChildClass : BaseClass<int> 
{ 
} 

przyczyny to:

Aktywa/ChildClass.cs (8,14): error CS1502: Najlepszy mecz dla przeciążona metoda klasy bazowej < int> .BaseClass (int, bool)” ma pewne nieprawidłowe argumenty

Aktywa/ChildClass.cs (8,14): error CS1503: Argument #1' cannot convert null 'wyrażenie wpisać `int'

Howev er, klasa bazowa z typów wartości mogą być stosowane w obszarach bez problemu:

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

Spojrzałem na DLL przy użyciu ILSpy i zauważyłem to:

public class BaseClass<T> 
{ 
    public T value; 
    public bool enabled; 
    public BaseClass(T value = null, bool enabled = true) 
    { 
     this.value = value; 
     this.enabled = enabled; 
    } 
} 

Zauważ, że default<T> w konstruktorze został zastąpiony przez null. To wydaje się być przyczyną problemu, ponieważ wartość zerowa byłaby nieprawidłową wartością dla typu wartości.

Co tu się dzieje?

EDYCJA: Jak odkryto w komentarzach, nie ma to miejsca, gdy drugi projekt jest skompilowany z VS2013 lub nowszymi wersjami Mono.

+1

To jest błąd kompilatora. Jaki to kompilator? – usr

+0

Visual Studio 2013 – Adam

+1

Po prostu próbowałem tego z VS 2013 i działa dobrze. –

Odpowiedz

4

Wygląda na to, że jest to błąd występujący w kompilatorze mono przed wersją 3.2.3 (@usr miał rację w swoim pierwszym komentarzu). Kompilator wstawia domyślne wartości parametrów do metadanych zespołu jako atrybuty (patrz this answer). Zweryfikowałem, że wynik ilspy jest zgodny z ildasm, który koduje default(T) do do do . Podejrzewam, że konwencja jest taka, że ​​ogólny kod default(T) jest zakodowany jako null, a kompilator, który je zużywa, powinien po prostu wiedzieć, jak go użyć. Wygląda na to, że jest on związany z this issue, jednak w oparciu o daty ten konkretny problem został naprawiony jakiś czas przed zgłoszeniem.

Powiązane problemy