"is null" vs "==null"

  • C#
  • .NET 7–8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Bluespide.

    Der Unterschied liegt darin, wie verglichen wird.

    Da Typen den == Operator überladen können, kann mit == nicht immer eine korrekte Prüfung auf null garantiert werden.

    Bei is wird der intrinsische Gleichheitsoperator verwendet und so immer eine korrekte Prüfung auf null garantiert.

    Was performancetechnisch besser ist, wird immer davon abhängen, was genau verglichen wird, mit welchem Operator.
    Zwei == müssen sich nicht gleich verhalten, je nachdem, welcher Typ genau verglichen wird.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „siycah“ ()

    Ich hab jetzt auf MS herumgelesen, bin schnell auf das Thema "Pattern-Matching" gestossen, was ich noch nie verstanden habe.
    Zusammengereimt habich mir diese Vermutung:
    der is-Operator wendet Pattern-Matching an (was immer das sein mag)
    Übrigens ebenso wird in switch-Statements Patternmatching angewendet.

    Dazu zwei Fragen:
    1. Sind meine Vermutungen richtig?
    2. Wenn ja: Gibt es weitere Vergleiche mit Pattern-Matching?
    Nicht ganz. Der Unterschied ist eigentlich oben schon von @siycah perfekt beschrieben. == ist ein Operator und als solcher auch überschreibbar. is ist kein Operator und fest implementiert.

    Das hier ist kein Pattern-Matching:

    C#-Quellcode

    1. if (o is string) {
    2. }


    Das hier schon:

    C#-Quellcode

    1. if (o is string str) {
    2. }


    is benutzt Pattern-Matching also, wenn du den Cast-Versuch machst und das Ergebnis direkt abspeicherst in einer Variable (hier str), weil er dann sozusagen auf den Typen string str matched. Ist übrigens auch gleichzeitig eine != null abfrage. Bei null würde er nicht matchen.

    Das ist ganz praktisch bei Abfragen wie z.B.

    C#-Quellcode

    1. if (someArray.FirstOrDefault(x => x.Length > 33) is Stream stream) {
    2. // EntryFound!
    3. }


    Oder als Switch-Expression:

    C#-Quellcode

    1. string myStringValue = o switch {
    2. string str => str,
    3. MemoryStream sm => sm.Length.ToString(),
    4. double db => db.ToString(),
    5. _ => "Everything else",
    6. };


    Auch mit Bedingungen:

    C#-Quellcode

    1. string myStringValue = o switch {
    2. string str => str,
    3. MemoryStream sm when sm.Length > 23 => sm.Length.ToString(),
    4. MemoryStream sm when sm.Length < 500 => sm.Length.ToString(),
    5. double db => db.ToString(),
    6. _ => "Everything else",
    7. };


    Sieht aber richtig komisch aus mit nur Operatoren:

    C#-Quellcode

    1. string myStringValue = o switch {
    2. < 0.4 => "Kleiner!",
    3. > 0.8 => "Größer!",
    4. _ => "Was?",
    5. };


    Auch in if-Abfragen:

    C#-Quellcode

    1. if (d is > 2 or < 5 or 7 and not 3) {
    2. }


    Richtig Wild wird es dann, wenn du die { } als Matching benutzt:

    C#-Quellcode

    1. if (someArray.FirstOrDefault(x => x.Length > 33) is { } stream) {
    2. // EntryFound!
    3. }


    Heißt erstmal nur != null, also ein Objekt mit nix definiert. Kann aber noch Bedingungen enthalten z.B. (ein Objekt, was die Property "Position=23" oder "Position > 400" und "CanRead=true" hat):

    C#-Quellcode

    1. if (someArray.FirstOrDefault(x => x.Length > 33) is { Position: 23 or > 400, CanRead: true } stream) {
    2. // EntryFound!
    3. }


    Und jetzt in .NET8 sind ja auch noch die Listen-Matches hinzugekommen....