Подтвердить что ты не робот

Использование ключевого слова по умолчанию в DLL

Я столкнулся с действительно странной проблемой при использовании ключевого слова default в DLL-проекте. В моем проекте 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, он работает отлично. Я могу создавать классы, которые выводятся из этого базового класса без проблем. Но, как только я пытаюсь использовать DLL в другом проекте (скомпилированном с Mono 2.0.0), получение из базового класса со значением типа вызывает ошибку компилятора. Это:

public class ChildClass : BaseClass<int>
{
}

вызывает следующее:

Активы/ChildClass.cs(8,14): ошибка CS1502: наилучшее перегруженное соответствие метода для BaseClass <int> .BaseClass(int, bool) 'имеет некоторые недопустимые аргументы

Активы/ChildClass.cs(8,14): ошибка CS1503: аргумент #1' cannot convert null 'выражение для ввода `int'

Однако базовый класс со значениями типов может использоваться в полях без проблем:

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

Я просмотрел DLL, используя 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 будет недопустимым значением для типа значения.

Итак, что здесь происходит?

EDIT: как было обнаружено в комментариях, это не происходит, когда второй проект скомпилирован с VS2013 или с более новыми версиями Mono.

4b9b3361

Ответ 1

Кажется, это ошибка с монокомпилятором pre-3.2.3 (@usr был совершенно прав в своем первоначальном комментарии). Компилятор вставляет значения параметров по умолчанию в метаданные сборки как атрибуты (см. этот ответ). Я проверил, что вывод ilspy согласуется с ildasm, который кодирует от default(T) до .param [1] = nullref. Я подозреваю, что соглашение состоит в том, что общий default(T) закодирован как null, а компилятор-потребляющий должен просто знать, как его использовать. Это похоже на этот вопрос, однако на основе дат эта конкретная проблема была исправлена ​​за некоторое время до того, как это было сообщено.