webentwicklung-frage-antwort-db.com.de

Hat C # IsNullOrEmpty für List/IEnumerable?

Ich weiß, dass in der Regel leere Liste mehr als NULL ist. Aber ich werde NULL zurückgeben, hauptsächlich aus zwei Gründen

  1. Ich muss Nullwerte explizit überprüfen und behandeln, um Fehler und Angriffe zu vermeiden.
  2. Es ist einfach, anschließend eine ??-Operation auszuführen, um einen Rückgabewert zu erhalten.

Für Strings haben wir IsNullOrEmpty. Gibt es irgendetwas, das von C # selbst für List oder IEnumerable tut?

60
Eric Yin

nichts in das Framework eingebettet, aber es ist eine ziemlich einfache Erweiterungsmethode.

Siehe hier

/// <summary>
    /// Determines whether the collection is null or contains no elements.
    /// </summary>
    /// <typeparam name="T">The IEnumerable type.</typeparam>
    /// <param name="enumerable">The enumerable, which may be null or empty.</param>
    /// <returns>
    ///     <c>true</c> if the IEnumerable is null or empty; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null)
        {
            return true;
        }
        /* If this is a list, use the Count property for efficiency. 
         * The Count property is O(1) while IEnumerable.Count() is O(N). */
        var collection = enumerable as ICollection<T>;
        if (collection != null)
        {
            return collection.Count < 1;
        }
        return !enumerable.Any(); 
    }

Daniel Vaughan führt den zusätzlichen Schritt des Castings aus Performancegründen zu ICollection (wo möglich). Etwas, an das ich nicht gedacht hätte.

65
Matthew Vines

Late update: seit C # 6.0 kann der null-propagation-Operator verwendet werden, um eine kurze Aussage wie folgt auszudrücken:

if (enumerable?.Any() ?? false)

Anmerkung 1:?? false ist aus folgendem Grund erforderlich (Zusammenfassung/Zitat aus diesem Beitrag ):

Der ?.-Operator gibt null zurück, wenn ein untergeordnetes Mitglied null..__ ist. Aber [...] wenn wir versuchen, ein Nicht-Nullable-Mitglied zu bekommen, wie das Any()-Methode, die bool [...] zurückgibt, wird der Compiler "wrap" einen Rückgabewert in Nullable<>. Zum Beispiel wird Object?.Any() gib uns bool? (was Nullable<bool> ist), nicht bool. [...] Da es nicht implizit in bool umgewandelt werden kann, kann dieser Ausdruck nicht in if verwendet werden.

Anmerkung 2: als Bonus, die Aussage ist auch "threadsicher" (Zitat aus Antwort von dieser Frage ):

Wenn in einem Multithread-Kontext auf [Enumerable] von einem anderen .__ aus zugegriffen werden kann. thread (entweder weil es ein Feld ist, auf das zugegriffen werden kann, oder weil es in einem Lambda, das einem anderen Thread ausgesetzt ist, geschlossen ist .__). Wert kann bei jeder Berechnung anders sein [d. h. vordere Nullprüfung]

35
Teodor Tite

Es ist nichts eingebaut.

Es ist jedoch eine einfache Erweiterungsmethode:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
  if(enumerable == null)
    return true;

  return !enumerable.Any();
}
23
Oded
var nullOrEmpty = list == null || !list.Any();
9
Justin Niessner

Die vorherigen Antworten zu einer einfachen Erweiterungsmethode für C # 6.0+ zusammenfassen:

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;
1
Xipooo

Wie alle anderen gesagt haben, ist nichts in das Framework eingebaut, aber wenn Sie Castle verwenden, dann hat Castle.Core.Internal es.

using Castle.Core.Internal;

namespace PhoneNumbers
{
    public class PhoneNumberService : IPhoneNumberService
    {
        public void ConsolidateNumbers(Account accountRequest)
        {
            if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T>
            {
                return;
            }
            ...
1
Matt Frear

Wenn Sie alle Elemente abrufen müssen, falls sie nicht leer sind, funktionieren einige der Antworten hier nicht, da der Aufruf von Any() auf einer nicht rücklauffähigen Aufzählungskomponente ein Element "vergisst".

Sie könnten einen anderen Ansatz wählen und Nullen in Leergut verwandeln:

bool didSomething = false;
foreach(var element in someEnumeration ?? Enumerable.Empty<MyType>())
{
  //some sensible thing to do on element...
  didSomething = true;
}
if(!didSomething)
{
  //handle the fact that it was null or empty (without caring which).
}

Ebenso kann (someEnumeration ?? Enumerable.Empty<MyType>()).ToList() etc. verwendet werden.

1
Jon Hanna
var nullOrEmpty = !( list?.Count > 0 );
0
eddy white

für mich ist die beste isNullOrEmpty-Methode so

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
    return !enumerable?.Any() ?? true;
}
0
keipa

Ich habe den Vorschlag von Matthew Vines geändert, um das "Mögliche mehrfache Aufzählen von IEnumerable" zu vermeiden. (Siehe auch den Kommentar von Jon Hanna) 

public static bool IsNullOrEmpty(this IEnumerable items)
    => items == null
    || (items as ICollection)?.Count == 0
    || !items.GetEnumerator().MoveNext();

... und der Unit-Test:

[Test]
public void TestEnumerableEx()
{
    List<int> list = null;
    Assert.IsTrue(list.IsNullOrEmpty());

    list = new List<int>();
    Assert.IsTrue(list.IsNullOrEmpty());

    list.AddRange(new []{1, 2, 3});
    Assert.IsFalse(list.IsNullOrEmpty());

    var enumerator = list.GetEnumerator();
    for(var i = 1; i <= list.Count; i++)
    {
        Assert.IsFalse(list.IsNullOrEmpty());
        Assert.IsTrue(enumerator.MoveNext());
        Assert.AreEqual(i, enumerator.Current);
    }

    Assert.IsFalse(list.IsNullOrEmpty());
    Assert.IsFalse(enumerator.MoveNext());
}
0
Georg