Jak Mogę zwrócić NULL Z metody generycznej w C#?

Mam metodę generyczną z tym (atrapa) kodem (tak, Wiem, że IList ma predykaty, ale mój kod nie używa IList, ale jakiejś innej kolekcji, w każdym razie to nie ma znaczenia dla pytania...)

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.
}

To daje mi błąd budowania

" nie można przekonwertować null na parametr type 'T', ponieważ może być typem wartości. Rozważ użycie 'default(t)'."

Czy mogę uniknąć tego błędu?

 458
Author: edosoft, 2008-11-19

11 answers

Dwie opcje:

  • Return default(T) co oznacza, że zwrócisz null Jeśli T jest typem odniesienia (lub typem wartości nullable), 0 dla int, '\0' dla char, itd.
  • Ogranicz T jako typ odniesienia z where T : class ograniczeniem, a następnie zwróć null jako normalny
 805
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 21:00:58
return default(T);
 69
Author: Ricardo Villamil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-19 14:56:23

Możesz po prostu dostosować swoje ograniczenia:

where T : class

Wtedy zwracanie null jest dozwolone.

 24
Author: TheSoftwareJedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-31 19:27:54

Dodaj ograniczenie klasy jako pierwsze ograniczenie do typu ogólnego.

static T FindThing<T>(IList collection, int id) where T : class, IThing, new()
 10
Author: Min,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-19 15:02:27
  1. Jeśli masz obiekt to musisz wpisać

    return (T)(object)(employee);
    
  2. Jeśli chcesz zwrócić null.

    return default(T);
    
 6
Author: 2 revs, 2 users 86%user725388,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 15:15:34

Inną opcją byłoby dodanie tego na końcu deklaracji:

    where T : class
    where T: IList

W ten sposób pozwoli Ci zwrócić null.

 5
Author: BFree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-19 15:01:37

Rozwiązanie thesoftwarejedi works,

Możesz też zarchiwizować go za pomocą kilku typów value i 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;
}
 2
Author: devi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-02 10:11:55

Poniżej znajdują się dwie opcje, których możesz użyć

return default(T);

Lub

where T : class, IThing
 return null;
 2
Author: Jaydeep Shil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 19:08:34

Przyjmij zalecenie błędu... oraz Użytkownika default(T) LUB new T.

Będziesz musiał dodać porównanie w kodzie, aby upewnić się, że było poprawne dopasowanie, Jeśli pójdziesz tą drogą.

W przeciwnym razie, potencjalnie rozważ parametr wyjściowy dla "dopasowanie znalezione".

 1
Author: Mitchel Sellers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 15:17:57

Oto przykład roboczy dla wartości zwracanych przez 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
Author: Luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-12 01:24:45

Kolejna alternatywa dla 2 odpowiedzi przedstawionych powyżej. Jeśli zmienisz Typ zwracania na object, możesz zwrócić null, jednocześnie rzucając inny niż null return.

static object FindThing<T>(IList collection, int id)
{
    foreach T thing in collecion
    {
        if (thing.Id == id)
            return (T) thing;
    }
    return null;  // allowed now
}
 0
Author: Jeson Martajaya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-14 12:52:00