485 Stimmen

Ist es besser, null oder eine leere Sammlung zurückzugeben?

Das ist eine Art eine allgemeine Frage (aber ich bin mit C#), was ist der beste Weg (Best Practice), geben Sie null oder leere Sammlung für eine Methode, die eine Sammlung als Rückgabetyp hat?

0 Stimmen

Dies ist eine subjektive Frage, bei der es auf beiden Seiten leidenschaftliche Gläubige gibt. Es gibt keine allgemein anerkannte "beste Praxis".

5 Stimmen

1 Stimmen

Nun, es gibt eine bewährte Praxis, von der es aber auch begründete Ausnahmen gibt.

565voto

Leere Sammlung. Immer.

Das nervt:

if(myInstance.CollectionProperty != null)
{
  foreach(var item in myInstance.CollectionProperty)
    /* arrgh */
}

Es gilt als bewährte Praxis, NIEMALS eine null wenn eine Sammlung oder Aufzählung zurückgegeben wird. IMMER eine leere Aufzählung/Auflistung zurückgeben. Dies verhindert den oben erwähnten Unsinn und verhindert, dass Ihr Auto von Kollegen und Benutzern Ihrer Klassen mit Eiern beworfen wird.

Wenn es um Eigenschaften geht, setzen Sie Ihre Eigenschaft immer nur einmal und vergessen Sie sie.

public List<Foo> Foos {public get; private set;}

public Bar() { Foos = new List<Foo>(); }

In .NET 4.6.1 können Sie dies sehr stark einschränken:

public List<Foo> Foos { get; } = new List<Foo>();

Wenn es um Methoden geht, die Aufzählungen zurückgeben, können Sie einfach eine leere Aufzählung anstelle von null ...

public IEnumerable<Foo> GetMyFoos()
{
  return InnerGetFoos() ?? Enumerable.Empty<Foo>();
}

使用方法 Enumerable.Empty<T>() kann als effizienter angesehen werden als die Rückgabe einer neuen leeren Sammlung oder eines Arrays.

39 Stimmen

Ich stimme mit Will überein, aber ich denke, dass "immer" ein wenig übertrieben ist. While an empty collection might mean "0 items", returning Null could mean "no collection at all" - eg. if you are parsing HTML, looking for an <ul> with id="foo", <ul id="foo"></ul> could return empty collection; if there is no <ul> with id="foo" a null return would be better (unless you want to handle this case with an exception)

39 Stimmen

Es ist nicht immer eine Frage, ob "man einfach ein leeres Array zurückgeben kann", sondern eher, ob ein leeres Array im aktuellen Kontext irreführend sein könnte oder nicht. Ein leeres Array bedeutet tatsächlich etwas, ebenso wie null. Zu sagen, dass man immer ein leeres Array und nicht null zurückgeben sollte, ist fast so irreführend wie zu sagen, dass eine boolesche Methode immer true zurückgeben sollte. Beide möglichen Werte vermitteln eine Bedeutung.

1 Stimmen

+ an Bozho. Ich kann sehen, tun dies in einem ViewModel in WPF, wie Sie DataTrigger verwenden können, um UI-Darstellungen zu wechseln, wenn eine Eigenschaft ist null . Das bedeutet nicht, dass Sie haben zu tun, und eine Sammlungseigenschaft, die Folgendes zurückgibt null in jedem anderen Fall wäre das eine sehr schlechte Praxis...

166voto

RichardOD Punkte 28349

Von der Rahmengestaltungsrichtlinien 2. Auflage (S. 256):

Geben Sie KEINE Nullwerte von Sammlungseigenschaften oder von Methoden die Sammlungen zurückgeben. Geben Sie eine leere Sammlung oder ein leeres Array zurück.

Hier ist ein weiterer interessanter Artikel über die Vorteile der Nichtrückgabe von Nullen (ich habe versucht, etwas in Brad Abrams Blog zu finden, und er hat auf den Artikel verwiesen).

Bearbeiten - Da Eric Lippert nun auf die ursprüngliche Frage geantwortet hat, möchte ich auch Link zu seinem ausgezeichneten Artikel .

38 Stimmen

+1. Es ist immer die beste Praxis, die Gestaltungsrichtlinien des Rahmens zu befolgen, es sei denn, Sie haben einen sehr, SEHR guten Grund, dies nicht zu tun.

0 Stimmen

@Will, absolut. Das ist es, was ich verfolge. Ich habe nie einen Grund gefunden, etwas anderes zu tun.

0 Stimmen

Ja, das ist es, was du verfolgst. Aber in Fällen, in denen APIs, auf die Sie sich verlassen, sich nicht daran halten, sind Sie "gefangen" ;)

95voto

Bozho Punkte 570413

Abhängig von Ihrem Vertrag und Ihr konkreter Fall . Im Allgemeinen ist es am besten, leere Sammlungen zurückzugeben , aber manchmal ( selten ):

  • null könnte etwas Spezifischeres bedeuten;
  • Ihr API (Vertrag) könnte Sie zur Rückgabe zwingen null .

Einige konkrete Beispiele:

  • eine UI-Komponente (aus einer Bibliothek außerhalb Ihrer Kontrolle), könnte eine leere Tabelle darstellen, wenn eine leere Auflistung übergeben wird, oder überhaupt keine Tabelle, wenn null übergeben wird.
  • in einem Object-to-XML (JSON/whatever), wobei null würde bedeuten, dass das Element fehlt, während eine leere Sammlung eine redundante (und möglicherweise falsche) <collection />
  • Sie verwenden oder implementieren eine API, die ausdrücklich festlegt, dass null zurückgegeben/übergeben werden soll.

4 Stimmen

@Bozho- einige interessante Beispiele hier.

2 Stimmen

Ich würde irgendwie Ihren Punkt sehen, obwohl ich nicht denke, Sie sollten Sie Code um andere Fehler und per Definition 'null' in c# bauen nunca bedeutet etwas Bestimmtes. Der Wert Null ist definiert als "keine Information" und daher ist die Aussage, dass er eine bestimmte Information enthält, ein Oximoron. Deshalb besagen die .NET-Richtlinien, dass man eine leere Menge zurückgeben sollte, wenn die Menge tatsächlich leer ist: "Ich weiß nicht, wo die erwartete Menge hin ist".

14 Stimmen

Nein, es bedeutet "es gibt keine Menge" und nicht "die Menge hat keine Elemente"

36voto

Jeffrey L Whitledge Punkte 55524

Es gibt noch einen weiteren Punkt, der noch nicht erwähnt wurde. Betrachten Sie den folgenden Code:

    public static IEnumerable<string> GetFavoriteEmoSongs()
    {
        yield break;
    }

Die C#-Sprache gibt beim Aufruf dieser Methode einen leeren Enumerator zurück. Um mit dem Sprachdesign (und damit den Erwartungen der Programmierer) übereinzustimmen, sollte daher eine leere Sammlung zurückgegeben werden.

1 Stimmen

Ich glaube nicht, dass dies technisch gesehen eine leere Sammlung ergibt.

3 Stimmen

@FryGuy - Nein, tut es nicht. Es gibt ein Enumerable-Objekt zurück, dessen GetEnumerator()-Methode einen Enumerator zurückgibt, der (in Analogie zu einer Sammlung) leer ist. Das heißt, die MoveNext()-Methode des Enumerators gibt immer false zurück. Der Aufruf der Beispielmethode gibt weder null zurück, noch ein Enumerable-Objekt, dessen GetEnumerator()-Methode null zurückgibt.

32voto

George Polevoy Punkte 7073

Leere ist viel verbraucherfreundlicher.

Es gibt eine klare Methode, um eine leere Aufzählung zu erstellen:

Enumerable.Empty<Element>()

2 Stimmen

Danke für den tollen Trick. Ich war instanziieren eine leere List<T>() wie ein Idiot, aber das sieht viel sauberer und ist wahrscheinlich ein wenig effizienter zu.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X