Einfaches Equals mit null prüfung?



  • Wie könnte man möglichst einfach ein equals bauen welches auch null werte berücksichtig. Sofern eine Klasse mehrere Members hat, sollte equals ja alle members prüfen (bzw vorzeitig abbrechen etc...) Bisher habe ich für jedes member das equals mit den jeweiligen member des anderen Objektes aufgerufen

    public bool Equals(MyObjectType other)
    {
       return this.m_foo.Equals(other.m_foo) && this.m_bar.Equals(other.m_bar);
    }
    

    Dumm nur das dies bei null Werten in die Hose geht. Um null zu berücksichtigen muss ich das ganze also in einer komplizierte If/Else Abfrage einbauen, die mit jeden member größer wird.

    public bool Equals(MyObjectType other)
    {
       if (this.m_foo != null && other.m_foo == null)
         return false
       else if (this.m_foo == null && other.m_foo != null)
         return false
       else if (!this.m_foo.Equals(other.m_foo))
         return false;
       //Do the same with bar
       ...
       //return
       return true
    }
    

    Ich halte das für so wenig Ziel für relativ viel Aufwand. Gibts da ggf noch ne einfachere Formulierung die mir nur spontan jetzt nicht einfällt?



  • So vielleicht:

    public bool Equals(MyObjectType other)
    {
      if(this.m_foo != null && other.m_foo != null)
        return this.m_foo.Equals(other.m_foo);
      return (this.m_foo == null) == (other.m_foo == null);
    }
    


  • Ach moment, mit Bar dann vieleicht eher so:

    public bool Equals(MyObjectType other)
    {
      if(this.m_foo != null && other.m_foo != null && ! this.m_foo.Equals(other.m_foo))
        return false;
      if(this.m_bar != null && other.m_bar != null && ! this.m_bar.Equals(other.m_bar))
        return false;
      return ((this.m_foo == null) == (other.m_foo == null)) && ((this.m_bar == null) == (other.m_bar == null));
    }
    

  • Administrator

    return (m_foo == other.m_foo) ? (m_foo != null ? m_foo.Equals(other.m_foo) : true) : false
        && (m_bar == other.m_bar) ? (m_bar != null ? m_bar.Equals(other.m_bar) : true) : false;
    // etc.
    

    Kompakter, aber besser? 🙂
    Vielleicht mit einer Hilfsfunktion?

    public static bool CheckMemberEqual<T>(T lhs, T rhs)
      where T : class, IEquatable<T>
    {
      if(lhs != rhs)
      {
        return false;
      }
    
      return lhs != null ? lhs.Equals(rhs) : true;
    }
    
    public bool Equals(MyObjectType other)
    {
      return CheckMemberEqual(m_foo, other.m_foo)
          && CheckMemberEqual(m_bar, other.m_bar);
    }
    

    Grüssli



  • Dravere schrieb:

    Kompakter, aber besser? 🙂

    Nö, nicht besser, da falsch :p
    Bei m_foo != other.m_foo würdest du ja immer false zurück geben.


  • Administrator

    Jockelx schrieb:

    Dravere schrieb:

    Kompakter, aber besser? 🙂

    Nö, nicht besser, da falsch :p
    Bei m_foo != other.m_foo würdest du ja immer false zurück geben.

    😕 seltsam erklärt, aber ich glaube, ich habe das Problem erkannt 🙂
    Das Prinzip sollte aber trotzdem gehen ...

    public static bool CheckMemberEqual<T>(T lhs, T rhs)
      where T : class, IEquatable<T>
    {
      if(lhs == rhs)
      {
        return true;
      }
      else if(lhs == null || rhs == null)
      {
        return false;
      }
    
      return lhs.Equals(rhs);
    }
    

    Jetzt aber ... oder?
    Naja, ich gehe mich jetzt erstmal duschen, anziehen und danach einen Kaffee trinken 😃

    Grüssli



  • Die Sache mit der static Hilfsmethode gefällt mir sehr gut. Geht das ganze auch für nullable typen?
    Ich denke da brauche ich ne zweite Hilfsmethode, aber wie deklariere ich die?


  • Administrator

    Fedaykin schrieb:

    Ich denke da brauche ich ne zweite Hilfsmethode, aber wie deklariere ich die?

    Die gibt es schon: Nullable.Equals<T>

    Grüssli



  • ahh Spitze, besten Dank.



  • Auf den Anfangsbeitrag bezogen:
    es gibt auch die statische Methode "Object.Equals":

    return Object.Equals(m_foo, other.m_foo);
    

    welche auch null-Werte berücksichtigt -)



  • Th69 schrieb:

    Auf den Anfangsbeitrag bezogen:
    es gibt auch die statische Methode "Object.Equals":

    return Object.Equals(m_foo, other.m_foo);
    

    welche auch null-Werte berücksichtigt -)

    Ist nun auch eingebaut, und damit ist die Hilfsmethode wohl auch überflüssig. Wenn man sowas nicht oft gebraucht lernt man nicht was es so alles gibt. Leider hab ich das ganze wohl in ca 4 monaten wieder vergessen in denen ich sowas nicht brauche. Aber dennoch besten Dank dafür.


  • Administrator

    Th69 schrieb:

    Auf den Anfangsbeitrag bezogen:
    es gibt auch die statische Methode "Object.Equals":

    return Object.Equals(m_foo, other.m_foo);
    

    welche auch null-Werte berücksichtigt -)

    Danke für den Hinweis. Noch nie benötigt, aber trotzdem gut zu wissen 🙂

    Grüssli


Log in to reply