Как я могу вернуть NULL из универсального метода в C #? - PullRequest
495 голосов
/ 19 ноября 2008

У меня есть универсальный метод с этим (фиктивным) кодом (да, я знаю, что в IList есть предикаты, но мой код использует не IList, а какую-то другую коллекцию, в любом случае это не имеет значения для вопроса ...)

static T FindThing<T>(IList collection, int id) where T : IThing, new()
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return thing;
    }
    return null;  // ERROR: Cannot convert null to type parameter 'T' because it could be a value type. Consider using 'default(T)' instead.
}

Это дает мне ошибку сборки

"Невозможно преобразовать ноль в параметр типа 'T', потому что это может быть тип значения. Попробуйте вместо этого использовать default (T).

Можно ли избежать этой ошибки?

Ответы [ 11 ]

865 голосов
/ 19 ноября 2008

Два варианта:

  • Возврат default(T), что означает, что вы вернете null, если T является ссылочным типом (или типом значения Nullable), 0 для int, '\0' для char и т. Д. ( Таблица значений по умолчанию (C # Reference) )
  • Ограничьте T ссылочным типом с ограничением where T : class, а затем верните null как обычно
77 голосов
/ 19 ноября 2008
return default(T);
29 голосов
/ 19 ноября 2008

Вы можете просто настроить свои ограничения:

where T : class

Тогда возврат нуля разрешен.

11 голосов
/ 19 ноября 2008

Добавьте ограничение класса как первое ограничение к вашему универсальному типу.

static T FindThing<T>(IList collection, int id) where T : class, IThing, new()
6 голосов
/ 06 августа 2012
  1. Если у вас есть объект, то нужно набрать

    return (T)(object)(employee);
    
  2. если вам нужно вернуть ноль.

    return default(T);
    
6 голосов
/ 19 ноября 2008

Другой вариант - добавить это в конец вашей декларации:

    where T : class
    where T: IList

Таким образом, вы сможете вернуть ноль.

5 голосов
/ 24 сентября 2015

Ниже приведены две опции, которые вы можете использовать

return default(T);

или

where T : class, IThing
 return null;
3 голосов
/ 02 декабря 2011

Решение TheSoftwareJedi работает,

также вы можете заархивировать его, используя пару типов value и nullable:

static T? FindThing<T>(IList collection, int id) where T : struct, IThing
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return thing;
    }
    return null;
}
1 голос
/ 12 марта 2015

Вот рабочий пример для возвращаемых значений Nullable Enum:

public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct
{
    return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value);
}
1 голос
/ 19 ноября 2008

Примите рекомендацию об ошибке ... и либо пользователь default(T), либо new T.

Вы должны будете добавить сравнение в своем коде, чтобы убедиться, что оно соответствует действительности, если вы идете по этому пути.

В противном случае, возможно, рассмотрим выходной параметр для "совпадение найдено".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...