2013-07-05 8 views
35

Nel caso di utilizzo di enumerazioni, è meglio usare:c eguali # enum() vs ==

if (enumInstance.Equals(MyEnum.SomeValue)) 

o per utilizzare

if (enumInstance == MyEnum.SomeValue) 

Sono loro eventuali considerazioni importanti utilizzando uno contro il altro?

+0

Mi sento come questo è stato probabilmente risposto prima, non riesco proprio a trovare dove. Se è stata data una risposta fammi sapere e ho cancellato questa domanda – ToddBFisher

+5

praticamente * ogni * domanda posta su SO è stata posta qui prima ... dovrebbe esserci un badge per fare una domanda davvero unica. –

+0

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

risposta

39

Se il tipo in fase di compilazione di enumInstance è il tipo enum, stai bene con ==.

Se il tipo in fase di compilazione della enumInstance è Enum, ValueType o Object, è necessario utilizzare Equals. (Si verificherà un errore in fase di compilazione se si tenta di utilizzare == in tal caso.)

Si noti che l'enumerazione attualmente viola le convenzioni di denominazione .NET, che normalmente corrisponde a MyEnum.Value.

+0

nel caso in cui sia enum dichiarato che ha più proprietà/valori impostati sul stesso numero, fa .Equals() convertirlo in rappresentazione numerica prima di confrontare? Con ciò, è contro le migliori pratiche avere più valori enum/valori con lo stesso valore numerico sottostante? – ToddBFisher

+0

@ToddBFisher: There * is * solo una rappresentazione numerica. Due nomi per lo stesso valore hanno ancora lo stesso valore. In alcuni casi può essere utile avere più nomi con lo stesso valore, ma è raro e dovrebbe essere usato solo quando vuoi veramente che significhi la stessa cosa. Un esempio potrebbe essere se una versione precedente avesse un errore di battitura in un unico nome e si volesse correggere l'errore di battitura senza rompere il vecchio codice sorgente. –

+0

Questo ha causato un bug molto subdolo, che ha coinvolto un metodo di estensione di confronto 'params Func []' su una raccolta generica. – Michael

19

Utilizzando == invece di Equals è un po 'più veloce, non c'è bisogno di box enumerazioni e nessuna funzione chiamate necessarie qui è esempio di codice C# e ha generato MSIL per esso:

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 

Come si può vedere == genera istruzioni CEQ, metodo equals misura Misura boxe e callvirt

+3

+1 per il montaggio –

0

V'è un caso che le altre risposte qui non hanno detto che potrebbero aiutare gli altri S.

Con C# il tipo sottostante di enum è un integrale. Perché è un integrale, puoi logicamente O le enumerazioni insieme.

Quando si utilizza uno dei metodi precedenti per l'uguaglianza, se le enumerazioni sono logicamente OR insieme.

Quindi, per alcuni casi speciali, ad esempio l'utilizzo di enumerazioni come flag, è necessario che sia logico e il caso che si sta verificando con il primo, prima di verificare l'uguaglianza.

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

o

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

In senso stretto è più sicuro da usare "==" con enumerazioni.

Un elenco completo dei possibili tipi enum può essere trovato qui: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum