Оператор '?' не может быть применен к операнду типа 'T'

Пытаясь сделать Feature универсальный, а потом вдруг компилятор сказал

Оператор '?' не может быть применен к операнду типа 'T'

Вот код

public abstract class Feature<T>
{
    public T Value
    {
        get { return GetValue?.Invoke(); } // here is error
        set { SetValue?.Invoke(value); }
    }

    public Func<T> GetValue { get; set; }
    public Action<T> SetValue { get; set; }
}

Вместо этого можно использовать этот код

get
{
    if (GetValue != null)
        return GetValue();
    return default(T);
}

Но мне интересно, как исправить эту симпатичную однострочную версию C# 6.0.

3 ответа

Решение

Поскольку не все может быть nullнужно сузить T быть чем-то обнуляемым (иначе object). Структуры не могут быть нулевыми и не могут перечислять.

Добавление where на class решает проблему:

public abstract class Feature<T> where T : class

Так почему же это не работает?

Invoke() доходность T, Если GetValue является null, ? Оператор устанавливает возвращаемое значение типа T в nullчто не может. Если T является int например, это не может сделать это обнуляемым (int?) так как фактический тип требуется (T знак равно int) нет

Если вы измените T быть int в вашем коде вы увидите проблему очень четко. Конечный результат того, что вы спрашиваете, таков:

get
{
    int? x = GetValue?.Invoke();
    return x.GetValueOrDefault(0);
}

Это не то, что оператор с нулевым распространением сделает для вас. Если вы вернетесь к использованию default(T) он точно знает, что делать, и вы избегаете "проблемного" нуль-распространения.

T должен быть ссылочным типом или обнуляемым типом

public abstract class Feature<T> where T : class
{
    // ...
}

Насколько я знаю ?. оператор жестко запрограммирован для работы с nullто есть он работает для ссылочных типов или типов значений, допускающих значение NULL, но не для нормальных типов значений. Проблема, вероятно, что оператор возвращает null если выражение было null вместо default(T),

Вы можете исправить это, ограничив T в class Вот.

Другие вопросы по тегам