2013-07-05 5 views
35

Im Fall von Aufzählungen verwenden, ist es besser zu nutzen:C# Enum equals() vs ==

if (enumInstance.Equals(MyEnum.SomeValue)) 

oder verwenden

if (enumInstance == MyEnum.SomeValue) 

Gibt es irgendwelche wichtigen Überlegungen eine vs die Verwendung von andere?

+0

ich so das Gefühl, wahrscheinlich bevor beantwortet wurde, kann ich einfach nicht, wo finden:

Eine vollständige Liste der möglichen Aufzählungstypen sind hier zu finden. Wenn es beantwortet wurde, lass es mich wissen und ich werde diese Frage löschen – ToddBFisher

+5

ziemlich * jede * Frage, die auf SO gestellt wurde hier schon einmal gefragt ... es sollte ein Abzeichen für eine wirklich einzigartige Frage sein. –

+0

http://stackoverflow.com/questions/814878/c-sharp-difference-between-and-equals – jAC

Antwort

39

Wenn der Kompilierzeittyp enumInstance der Aufzählungstyp ist, ist == in Ordnung.

Wenn der Kompilierung-Typ von enumInstanceEnum ist, ValueType oder Object, müssen Sie Equals verwenden. (Sie erhalten einen Fehler bei der Kompilierung, wenn Sie in diesem Fall versuchen, == zu verwenden.)

Beachten Sie, dass Ihre enum derzeit gegen .NET-Namenskonventionen verstößt - normalerweise wäre dies MyEnum.Value.

+0

für den Fall deklarieren können, dass eine Enumeration mit mehreren Eigenschaften/Werten definiert ist gleiche Zahl, konvertiert .Equals() es vor dem Vergleich in seine numerische Darstellung? Wäre es also gegen die Best Practices, wenn mehrere enum-Eigenschaften/Werte denselben zugrunde liegenden numerischen Wert haben? – ToddBFisher

+0

@ ToddBFisher: Es * ist * nur eine numerische Darstellung. Zwei Namen für denselben Wert haben immer noch denselben Wert. Es kann in einigen Fällen nützlich sein, mehrere Namen mit demselben Wert zu haben, aber es ist selten und sollte nur verwendet werden, wenn Sie wirklich wollen, dass sie dasselbe bedeuten. Ein Beispiel wäre, wenn eine frühere Version einen Tippfehler in einem Namen hätte und Sie den Tippfehler korrigieren wollten, ohne den alten Quellcode zu beschädigen. –

+0

Dies verursachte einen sehr hinterhältigen Fehler, der eine 'params Func []' Vergleichserweiterungsmethode für eine generische Sammlung beinhaltete. – Michael

19

Mit == statt Equals ist ein bisschen schneller, besteht keine Notwendigkeit, hier benötigt Aufzählungen und keine Funktionen Anrufe boxen ist Probe C# -Code und erzeugt MSIL für sie:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var instance = MyEnum.First; 

      if (instance == MyEnum.First) 
      { 
       Console.WriteLine("== Called"); 
      } 

      if (instance.Equals(MyEnum.First)) 
      { 
       Console.WriteLine("Equals called"); 
      } 

     }  
    } 

    enum MyEnum { First = 99, Second = 100} 

MSIL:

IL_0000: nop 
    IL_0001: ldc.i4.s 99 
    IL_0003: stloc.0 
    IL_0004: ldloc.0 
    IL_0005: ldc.i4.s 99 
    IL_0007: ceq 
    IL_0009: ldc.i4.0 
    IL_000a: ceq 
    IL_000c: stloc.1 
    IL_000d: ldloc.1 
    IL_000e: brtrue.s IL_001d 
    IL_0010: nop 
    IL_0011: ldstr  "== Called" 
    IL_0016: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001b: nop 
    IL_001c: nop 
    IL_001d: ldloc.0 
    IL_001e: box  ConsoleApplication1.MyEnum 
    IL_0023: ldc.i4.s 99 
    IL_0025: box  ConsoleApplication1.MyEnum 
    IL_002a: callvirt instance bool [mscorlib]System.Object::Equals(object) 
    IL_002f: ldc.i4.0 
    IL_0030: ceq 
    IL_0032: stloc.1 
    IL_0033: ldloc.1 
    IL_0034: brtrue.s IL_0043 
    IL_0036: nop 
    IL_0037: ldstr  "Equals called" 
    IL_003c: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_0041: nop 
    IL_0042: nop 
    IL_0043: ret 

Wie Sie == erzeugt ceq Anweisung sehen, Equals Methode performes Boxen und callvirt

+3

+1 für die Montage –

0

Es gibt einen Fall, dass die anderen Antworten hier nicht erwähnt, die anderen helfen können s.

Mit C# ist der zugrunde liegende Typ eines Enums ein Integral. Weil es ein Integral ist, können Sie logisch ODER die enums zusammen.

Wenn eine der oben genannten Methoden für die Gleichheit verwendet wird fehlschlagen, wenn Enums logisch OR verknüpft werden.

Also für einige spezielle Fälle, wie Enums als Flags zu verwenden, müssen Sie logisch und der Fall, mit dem Sie testen, mit dem ersten vor der Überprüfung auf Gleichheit.

if ((enumInstance & MyEnum.SomeValue).Equals(MyEnum.SomeValue)) 

oder

if ((enumInstance & MyEnum.SomeValue) == MyEnum.SomeValue) 

Streng genommen ist es am sichersten zu verwenden "==" mit Aufzählungen. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum