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


У меня есть следующий общий метод, но VS дает мне ошибку компиляции на этом. (Оператор'??'не может быть применен к операндам типа' T 'и'T')

public static T Method<T>(T model) where T : new()
{
    var m = model ?? new T();
}

кто-нибудь знает, почему?

Edit: возможно ли, что причина в том, что T может быть структурой в моем случае, а структура не является нулевым типом?

8 52

8 ответов:

вы должны добавить class ограничения:

public static T Method<T>(T model) where T : class, new()
{
    var m = model ?? new T();

    return m;
}

и вы должны вернуть m слишком!

Примечание: как отметил @KristofDegrave в своем комментарии, причина, по которой мы должны добавить class ограничение связано с тем, что T может быть типом значения, например int и с ?? оператор (null-coalescing) проверяет типы, которые могут быть null, поэтому мы должны добавить class ограничение для исключения типов значений.

Edit: ответ Элвина Вонга охватывал случай для типов с нулевым значением тоже; какие структуры на самом деле, но могут быть операндами ?? оператор. Просто знайте, что Method вернутся null без перегруженной версии Элвина, для типов с нулевым значением.

?? - это нуль-коалесцирующий оператора. Он не может быть применен к ненулевым типам. Так как T может быть что угодно, это может быть int или другой примитивный, ненулевой тип.

если вы добавите условие where T : class (должно быть указано перед new()) это сил T быть экземпляром класса, который может быть обнулен.

многие уже указали, что добавление class ограничение для общего решит проблему.

Если вы хотите, чтобы ваш метод был применим к Nullable<T> тоже можно добавить перегрузку для него:

// For reference types
public static T Method<T>(T model) where T : class, new()
{
    return model ?? new T();
}

// For Nullable<T>
public static T Method<T>(T? model) where T : struct
{
    return model ?? new T(); // OR
    return model ?? default(T);
}

вам нужно указать, что ваш T тип-это класс с ограничением на общий тип:

public static T Method<T>(T model) where T : class, new()
{
    return model ?? new T();
}

Так как T может быть любого типа, нет никакой гарантии, что T будет иметь статический ?? оператор или что тип T является нулевым.

?? Операторов (Справочник По C#)

в ?? оператор называется оператором слияния нулей и используется для определить значение по умолчанию для типы значений с нулевым значением или ссылка типы.

почему-то ?? оператор не может быть использован для ненулевых типов, даже если он должен быть эквивалентен model == null ? new T() : model и are допускается сравнение null с типом, не допускающим null.

вы можете получить именно то, что вы ищете без каких-либо дополнительных ограничений при использовании тернарного оператора, или оператор if:

public static T Method<T>(T model) where T : new()
{
   var m = model == null ? new T() : model;
}

model ?? new T() означает model == null ? new T() : model. Не гарантируется, что модель не является нулевой и == не может быть применен для null и ненулевой объект. Изменение ограничения на where T : class, new() должны работать.

отметьте T как "класс", и вы хорошо идти.