Как я могу вернуть NULL из универсального метода в C#?

У меня есть общий метод с этим (фиктивным) Кодом (да, я знаю, что 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.
}

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

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

могу ли я избежать этой ошибки?

11 ответов


два варианта:

  • возвращение default(T) Что означает, что вы вернетесь null если T-ссылочный тип (или тип значения с нулевым значением),0 на int, '' на char, etc.
  • ограничить T, чтобы быть ссылочным типом с where T : class ограничение, а затем return null как обычно

return default(T);

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

where T : class

тогда возврат null разрешен.


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

static T FindThing<T>(IList collection, int id) where T : class, IThing, new()

  1. если у вас есть объект, то нужно типизировать

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

    return default(T);
    

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

    where T : class
    where T: IList

таким образом, это позволит вам вернуть null.


решение 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;
}

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

return default(T);

или

where T : class, IThing
 return null;

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

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

в противном случае потенциально рассмотрим выходной параметр для "match found".


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

public static TEnum? ParseOptional<TEnum>(this string value) where TEnum : struct
{
    return value == null ? (TEnum?)null : (TEnum) Enum.Parse(typeof(TEnum), value);
}

еще одна альтернатива 2 ответам, представленным выше. Если вы измените тип возврата на object, вы можете вернуть null, в то же время отбрасывая ненулевое возвращение.

static object FindThing<T>(IList collection, int id)
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return (T) thing;
    }
    return null;  // allowed now
}