2013-07-05 16 views
35

対列挙型を使用する場合には、それが使用することをお勧めし:C#の列挙型のequals()==

if (enumInstance.Equals(MyEnum.SomeValue)) 

または

if (enumInstance == MyEnum.SomeValue) 

が対1を使用して任意の重要な検討事項である使用します他の?

+0

はおそらく、私はどこ見つけることができません前に回答されています。それは私に知らせてくださいと私はこの質問を削除されます – ToddBFisher

+5

かなり*すべての*質問が尋ねられたので、これまでにここに尋ねられている...本当にユニークな質問をするためのバッジがある必要があります。 –

+0

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

答えて

39

enumInstanceのコンパイル時のタイプが列挙型の場合は、==で問題ありません。

enumInstanceのコンパイル時の型がEnumValueTypeまたはObjectある場合は、Equalsを使用する必要があります。 (その場合には==を使用しようとするとコンパイル時エラーが発生します)。

enumは現在.NETネーミング規則に違反しています。通常はMyEnum.Valueです。

+0

の場合、複数のプロパティ/値を持つenumが宣言されている場合.Equals()を比較する前に数値表現に変換しますか?それで、複数のenumプロパティ/値が同じ基礎となる数値を持つようにするのはベストプラクティスに反するのでしょうか? – ToddBFisher

+0

@ToddBFisher:数値表現のみ*です。同じ値の2つの名前は、実際には同じ値を持ちます。場合によっては同じ値を持つ複数の名前を持つことは有益かもしれませんが、まれであり、本当に同じものを意味する場合にのみ使用してください。 1つの例は、以前のバージョンに1つの名前のタイプミスがあって、古いソースコードを壊さずにタイプミスを修正したい場合です。 –

+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#では、基になる型の列挙型は整数です。これは整数なので、論理的にenumをORで結ぶことができます。

上記のいずれの方法を使用しても、enum同士が論理的に論理和をとっている場合、等価性が失われます。

フラグとしてenumを使用するなどの特殊なケースでは、等価性をチェックする前に、最初にテストするケースを論理的にANDする必要があります。

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

または

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

厳密にそれが列挙型で "==" を使用するのが最も安全です話します。

可能enum型の完全なリストはここで見つけることができます:私はこのように感じるhttps://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum