web-dev-qa-db-fra.com

c # enum est égal à () vs ==

Dans le cas d'utilisation d'énums, est-il préférable d'utiliser:

if (enumInstance.Equals(MyEnum.SomeValue))

ou d'utiliser

if (enumInstance == MyEnum.SomeValue)

Existe-t-il des considérations importantes concernant l’utilisation de l’un contre l’autre?

41
ToddBFisher

Si le type de compilation enumInstance est le type enum, vous pouvez utiliser ==.

Si le type de compilation enumInstance est Enum, ValueType ou Object, vous devez utiliser Equals. (Vous obtiendrez une erreur de compilation si vous essayez d'utiliser == dans ce cas.)

Notez que votre enum enfreint actuellement les conventions de nommage .NET - il s'agirait normalement de MyEnum.Value.

48
Jon Skeet

Utiliser == au lieu de Equals est un peu plus rapide, il n'est pas nécessaire de mettre des énumérations et aucun appel de fonction n'est nécessaire. Voici un exemple de code c # et généré par MSIL pour celui-ci:

 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

Comme vous pouvez le voir == génère l’instruction ceq, la méthode Equals effectue la boxe et le callvirt

23
Alexandr Mihalciuc

Il y a un cas que les autres réponses ici n'ont pas mentionné qui pourrait aider les autres.

Avec c #, le type sous-jacent d’énum est une intégrale. Comme il s’agit d’une intégrale, vous pouvez logiquement OR regrouper les énumérations.

Lorsque vous utilisez l'une des méthodes ci-dessus pour l'égalité, les échecs échouent si les énumérations sont logiquement associées OU.

Ainsi, dans certains cas particuliers, tels que l'utilisation d'énums comme indicateurs, vous devez logiquement ET le cas pour lequel vous effectuez le test, avant de vérifier l'égalité.

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

ou

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

À proprement parler, il est plus sûr d'utiliser "==" avec des énumérations.

Vous trouverez une liste complète des types d’énum possibles ici: https://docs.Microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

1
user3416682