2013-07-05 4 views
35

В случае использования перечислений, что лучше использовать:C# перечислений Equals() против ==

if (enumInstance.Equals(MyEnum.SomeValue)) 

или использовать

if (enumInstance == MyEnum.SomeValue) 

ли их какие-либо важные соображения, используя один В.С. Другие?

+0

Я чувствую, что это, вероятно, был дан ответ раньше, я просто не могу найти где. Если он был дан ответ, дайте мне знать, и я удалю этот вопрос – ToddBFisher

+5

в значительной степени * каждый * вопрос, заданный на SO, был задан здесь раньше ... должен быть значок для запроса поистине уникального вопроса. –

+0

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

ответ

39

Если тип времени компиляции enumInstance является типом перечисления, вы в порядке с ==.

Если тип во время компиляции enumInstance является Enum, ValueType или Object, вам нужно использовать Equals. (Вы получите ошибку времени компиляции, если попытаетесь использовать == в этом случае.)

Обратите внимание, что ваше перечисление в настоящее время нарушает соглашения об именах .NET - обычно это будет MyEnum.Value.

+0

в случае, если объявлено перечисление, которое имеет несколько свойств/значений, установленных в такое же число, делает .Equals() преобразует его в числовое представление перед сравнением? С этим, не против лучших методов, чтобы иметь несколько свойств/значений enum, имеют одно и то же базовое числовое значение? – ToddBFisher

+0

@ToddBFisher: есть * только числовое представление. Два имени для одного и того же значения по-прежнему имеют одинаковое значение. В некоторых случаях может быть полезно иметь несколько имен с одинаковым значением, но это редко, и их следует использовать только тогда, когда вы действительно хотите, чтобы они имели в виду одно и то же. Например, если предыдущая версия имела опечатку в одном имени, и вы хотели исправить опечатку, не нарушая старый исходный код. –

+0

Это вызвало очень хитрую ошибку, связанную с методом 'params Func []' метода сравнения в общей коллекции. – Michael

19

Использование == вместо Равных немного быстрее, нет необходимости в поле перечислений и никаких вызовов функций, необходимых здесь образец C# код и генерируется MSIL для него:

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 

Как вы можете видеть == генерирует Ceq инструкции, Равно метод performes бокс и callvirt

+3

+1 для сборки –

0

Существует случай, что другие ответы здесь не упоминается, что может помочь другим s.

С C# базовый тип перечисления является интегралом. Поскольку это интеграл, вы можете логически или перечислить вместе.

При использовании любого из приведенных выше методов для равенства не удастся, если перечисления логически совпадают.

Так что для некоторых особых случаев, таких как использование перечислений в виде флагов, вам нужно будет логически и к тому случаю, с которым вы тестируете, прежде чем проверять равенство.

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

или

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

Строго говоря, это безопаснее использовать "==" с перечислениями.

Полный список возможных типов перечислений можно найти здесь: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

Смежные вопросы