Gibt es einen pedantischen, auf der Enumerator-Theorie basierenden Grund, warum die Any() -Methode einen ArgumentNullException
für einen Null-Enumerable auslöst?Enumerable.Any <T> (diese IEnumerable <T> Quelle) sollte Null aufzählbar auch behandeln, sicher?
ich IEnumerable, wo immer möglich Sammlungen von Daten um passieren - aber in den meisten Fällen dann habe ich diese Art von Code:
public class Foo
{
public IEnumerable<IBar> Bars { get; set; }
}
////----
public static void UseAFoo(Foo foo)
{
//if Bars has something in it, then do something:
if(foo.Bars != null && foo.Bars.Any())
{
//blah
}
}
Oder
if((foo.Bars ?? Enumerable.Empty<IBar>()).Any())
{
//ugh!
}
oder ändern Sie die Eigenschaft Erklärung so :
public class Foo
{
private IEnumerable<IBar> _bars;
public IEnumerable<IBar> Bars
{
get { return _bars ?? Enumerable.Empty<IBar>(); }
set { _bars = value; }
}
}
Oder die 'effiziente' Art und Weise:
get { return _bars; }
set { _bars = value ?? Enumerable.Empty<IBar>(); }
In jedem Fall - es ist böse. Okay, ich kann meine eigene Erweiterungsmethode machen (was ich habe) - aber die Benennung ist ein bisschen schwierig, weil der beste Name schon vergeben ist! Ich bin für NotNullAndAny()
gegangen, aber ich mag es nicht.
Any()
(und es ist delegate-driven Bruder) sollte meiner Meinung nach false zurückgeben, wenn die Enumerable null ist - es sollte keine ArgumentNullException
werfen.
Aber dann wie ich am Anfang sage - gibt es hier einen versteckten Vertrag, den ich vermisse? Oder ist es nur Pedanterie;)
UPDATE
Ich hatte das Gefühl, dass der Konsens sein würde, dass alle Linq Erweiterungen ArgumentNullException
werfen sollen, auch den Fall von Any()
- und um ehrlich zu sein, während ich das Gefühl, dass der Fall noch für Any()
gemacht werden kann, sind die Argumente für nicht überzeugend genug, um die grundlegende Tatsache zu überwinden, dass, wenn ein Aufzählungszeichen null ist, keine allgemeine Operation zufriedenstellend abgeschlossen werden kann und daher eine Ausnahme ausgelöst werden muss.
Also werde ich mit einer zusätzlichen Extension-Methode NotNullAndAny()
gehen, um meinen Code zu bereinigen, wo Nullen vernünftigerweise möglich sind (und kein Fehler). In Fällen, in denen ein Null-Enumerable nicht erlaubt ist, werfe ich bereits ArgumentNullException
. In einigen Fällen ist es jedoch praktischer, den Verbrauchern meines Codes zu erlauben, eine Eigenschaft unset zu lassen, während meine Klassen nicht zwangsweise manuell implementierte Eigenschaften oder Standardkonstruktoren erfordern, um sicherzustellen, dass diese Eigenschaften niemals eine null
erhalten. Wenn das meine Wahl ist, dann übergebe ich meinen eigenen Code, um sowohl null als auch leer zu prüfen.
Einzige Sache ist jetzt, welche Antwort zu markieren als die Antwort! :)
Vielleicht ist dieser Beitrag von Eric Lippert interessant für Sie: [Null ist nicht leer] (http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty .aspx) –
Guter Beitrag - Danke für den Link. Ich verstehe, was er dort sagt - aber für mich scheint es nicht so zu sein, dass es mit der "Any" -Methode gewaschen wird. Ich hatte noch kein Szenario, in dem ich ein Null-Enumerable behandeln würde, das sich von einem leeren unterscheidet, bei dem die 'Any'-Methode mir Probleme bereiten würde, indem ich Nullen behandle. –
es ist eine Erweiterungsmethode - Sie können Ihre eigene Version implementieren, und importieren Sie sie gegenüber der Linq. Aber jetzt schreibst du einen Code, der hinter den Kulissen "mehr Magie" macht (Nullen verstecken), und er wird jemandem, der Linq gewohnt ist, nicht sofort vertraut sein. –