Gibt es einen kürzeren Weg, um das Folgende zu schreiben? (Etwas, das auf Null überprüft, ohne explizit != null
zu schreiben)
from item in list
where item.MyProperty != null
select item.MyProperty
Gibt es einen kürzeren Weg, um das Folgende zu schreiben? (Etwas, das auf Null überprüft, ohne explizit != null
zu schreiben)
from item in list
where item.MyProperty != null
select item.MyProperty
Sie können den OfType
-Operator verwenden. Er ignoriert Nullwerte in der Ausgangssequenz. Verwenden Sie einfach denselben Typ wie MyProperty
und es filtert nichts anderes aus.
// gegeben:
// public T MyProperty { get; }
var nonNullItems = list.Select(x => x.MyProperty).OfType();
Ich würde jedoch davon abraten. Wenn Sie nicht-null Werte auswählen möchten, was kann expliziter sein als zu sagen, dass Sie "die MyProperties aus der Liste, die nicht null sind", möchten?
Ich werde auf den Rat aller hören und es so belassen. Aber ich habe Ihre Antwort als akzeptiert markiert, weil Sie mir etwas gesagt haben, das ich nicht wusste.
Ich mag diese - sie hält den Code so sauber wie möglich, solange Sie sich daran erinnern können, wie OfType funktioniert! Andernfalls würde ich mit der zweiten Erweiterungsmethode von @CodeInChaos gehen.
Missbräuchliches Verwenden von OfType
als Null-Prüfung ist unintuitiv und schlechter Stil.
Sie könnten Ihre eigene Erweiterungsmethode definieren, aber das würde ich nicht empfehlen.
public static IEnumerable SelectNonNull(this IEnumerable sequence,Func projection)
{
return sequence.Select(projection).Where(e => e != null);
}
Ich mag diese Methode nicht, weil sie zwei Anliegen mischt. Das Projektieren mit Select
und das Filtern Ihrer Nullwerte sind separate Operationen und sollten nicht zu einer Methode kombiniert werden.
Ich würde lieber eine Erweiterungsmethode definieren, die nur überprüft, ob das Element nicht null ist:
public static IEnumerable WhereNotNull(this IEnumerable sequence)
{
return sequence.Where(e => e != null);
}
public static IEnumerable WhereNotNull(this IEnumerable sequence)
where T : struct
{
return sequence.Where(e => e != null).Select(e => e.Value);
}
Dies hat nur einen einzigen Zweck, nämlich das Überprüfen auf Null. Bei nullable-Werttypen wird es in den nicht nullable-Äquivalenten umgewandelt, da es sinnlos ist, den nullable-Wrapper für Werte zu erhalten, die nicht null sein können.
Mit dieser Methode wird Ihr Code zu:
list.Select(item => item.MyProperty).WhereNotNull()
Ich neige dazu, eine statische Klasse mit grundlegenden Funktionen für Fälle wie diese zu erstellen. Sie ermöglichen es mir, Ausdrücke wie
var myValues myItems.Select(x => x.Value).Where(Predicates.IsNotNull);
Und die Sammlung von Prädikatsfunktionen:
public static class Predicates
{
public static bool IsNull(T value) where T : class
{
return value == null;
}
public static bool IsNotNull(T value) where T : class
{
return value != null;
}
public static bool IsNull(T? nullableValue) where T : struct
{
return !nullableValue.HasValue;
}
public static bool IsNotNull(T? nullableValue) where T : struct
{
return nullableValue.HasValue;
}
public static bool HasValue(T? nullableValue) where T : struct
{
return nullableValue.HasValue;
}
public static bool HasNoValue(T? nullableValue) where T : struct
{
return !nullableValue.HasValue;
}
}
Bei Verwendung dieser Methode habe ich die Klasse in Is
umbenannt und das Is
-Präfix aus allen Methoden entfernt. Meiner Meinung nach macht es die Dinge lesbarer: collection.Where(Is.NotNull).Select...
Es ist besser, für generische Typen nicht die Operatoren == und != zu verwenden. Denn diese können überschrieben sein im Typ. Verwenden Sie ReferenceEquals(value, null)
// Wenn Sie überprüfen müssen, ob MyProperty aller Elemente nicht null ist
if (list.All(x => x.MyProperty != null))
// do something
// oder wenn Sie überprüfen müssen, ob mindestens ein Elementeigenschaft nicht null ist
if (list.Any(x => x.MyProperty != null))
// do something
Sie müssen jedoch immer auf null überprüfen
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.
11 Stimmen
Gibt es einen Grund, warum du nicht möchtest, dass der Code explizit darüber ist, was er tut?
0 Stimmen
Ich kenne keinen kürzeren Weg. Aber auch Ihre Version gilt allgemein als "lang".
0 Stimmen
Das ist ziemlich einfach. Aber wenn ein einzelnes Element in der Liste null ist, erhalten Sie eine NRE. Ihre where-Klausel muss sein item != null && item.MyProperty != null.
1 Stimmen
@R. Martinho Fernandes Für den nullable Werttyp und den neu hinzugefügten nullable Referenztyp gibt dir null-geprüft-dann-select immer noch einen nullable Typ.