c# 枚举equals() vs ==

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17492179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:38:19  来源:igfitidea点击:

c# enum equals() vs ==

c#enumsequals

提问by ToddBFisher

In the case of using enums, is it better to use:

在使用枚举的情况下,最好使用:

if (enumInstance.Equals(MyEnum.SomeValue))

or to use

或使用

if (enumInstance == MyEnum.SomeValue)

Are their any important considerations using one vs the other?

他们使用一个和另一个有什么重要的考虑吗?

采纳答案by Jon Skeet

If the compile-time type of enumInstanceis the enum type, you're fine with ==.

如果 的编译时类型enumInstance是枚举类型,则可以使用==.

If the compile-time type of enumInstanceis Enum, ValueTypeor Object, you need to use Equals. (You'll get a compile-time error if you try to use ==in that case.)

如果编译时类型enumInstanceEnum, ValueTypeor Object,则需要使用Equals. (如果您尝试==在这种情况下使用,则会出现编译时错误。)

Note that your enum currently violates .NET naming conventions - it would normally be MyEnum.Value.

请注意,您的枚举当前违反了 .NET 命名约定 - 通常是MyEnum.Value.

回答by Alexandr Mihalciuc

Using == instead of Equals is a bit quicker, there is no need to box enums and no functions calls needed here is sample c# code and generated MSIL for it:

使用 == 而不是 Equals 会快一点,不需要装箱枚举,这里不需要函数调用是示例 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:

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

As you can see == generates ceq instruction, Equals method performes boxing and callvirt

如您所见 == 生成 ceq 指令,Equals 方法执行装箱和 callvirt

回答by user3416682

There is a case that the other answers here have not mentioned that may help others.

有一种情况,这里的其他答案没有提到可能会帮助其他人。

With c# the underlying type of an enum is an integral. Because it is an integral, you can logically OR the enums together.

在 c# 中,枚举的基础类型是一个整数。因为它是一个积分,所以您可以在逻辑上将枚举组合在一起。

When using either of the above methods for equality will fail if enums are logically OR'd together.

如果枚举在逻辑上被 OR'd 在一起,则使用上述任何一种方法进行相等时都会失败。

So for some special cases, such as using enums as flags, you will need to logically AND the case you are testing for with first prior to checking for equality.

因此,对于某些特殊情况,例如使用枚举作为标志,在检查相等性之前,您需要首先对要测试的情况进行逻辑 AND 运算。

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

or

或者

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

Strictly speaking it's safest to use "==" with enums.

严格来说,对枚举使用“==”是最安全的。

A complete list of possible enum types can be found here: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

可以在此处找到可能的枚举类型的完整列表:https: //docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

回答by user1464603

As an extension to Jon Skeet's old answer, it is true that you get a compilation error when you compare Enum == YourActualEnum.Value, however when you do Enum == Enum, which compiles fine, it return false all the time.

作为 Jon Skeet 旧答案的扩展,确实会在您比较时遇到编译错误Enum == YourActualEnum.Value,但是当您这样做时Enum == Enum,编译正常,它始终返回 false。

public class TestClass
{
    public bool TestMethod1()
    {
        bool Result = false;

        Enum l_Value = TEST_ENUM.TEST_VALUE_1;

        Enum l_Check_Value = TEST_ENUM.TEST_VALUE_1;

        Result = l_Value == l_Check_Value;

        return Result;
    }

    public bool TestMethod2()
    {
        bool Result = false;

        TEST_ENUM l_Value = TEST_ENUM.TEST_VALUE_1;

        TEST_ENUM l_Check_Value = TEST_ENUM.TEST_VALUE_1;

        Result = l_Value == l_Check_Value;

        return Result;
    }

    public bool TestMethod3()
    {
        bool Result = false;

        Enum l_Value = TEST_ENUM.TEST_VALUE_1;

        Enum l_Check_Value = TEST_ENUM.TEST_VALUE_1;

        Result = l_Value.Equals(l_Check_Value);

        return Result;
    }

    public enum TEST_ENUM
    {
        TEST_VALUE_1,
        TEST_VALUE_2,
        TEST_VALUE_3
    }
}

if you try the following on a test app you'll get the following

如果您在测试应用程序上尝试以下操作,您将获得以下结果

Console.WriteLine("Method 1 result: {0}", myClass.TestMethod1());

Console.WriteLine("Method 2 result: {0}", myClass.TestMethod2());

Console.WriteLine("Method 3 result: {0}", myClass.TestMethod3());

you will get the following results

你会得到以下结果

Method 1 result: False Method 2 result: True Method 3 result: True

Method 1 result: False Method 2 result: True Method 3 result: True

If you wonder why would you ever compare Enum against Enum....I discovered it while trying to be smart while creating an EnumConverter and a FlagConvert for a WPF project. There you receive only an object value as parameter and for the flag converter specifically i wanted to provide a special text for when no flag was selected (i.e. the enum has a value of 0 which has no static member for it).

如果您想知道为什么要将 Enum 与 Enum 进行比较....我在为 WPF 项目创建 EnumConverter 和 FlagConvert 时尝试变得聪明时发现了它。在那里你只收到一个对象值作为参数,特别是对于标志转换器,我想为没有选择标志时提供一个特殊的文本(即枚举的值为 0,它没有静态成员)。

Nothing else worked (including value.Equals(0), value.Equals((int)0) ) except this:

除了这个之外没有其他工作(包括 value.Equals(0), value.Equals((int)0) ):

l_Source_Type = value.GetType();

if (l_Source_Type.IsDefined(typeof(FlagsAttribute)))
{
    Enum l_Value = (Enum)value;

    Enum l_Check_Value = (Enum)Enum.ToObject(l_Source_Type, 0);

    if (l_Value.Equals(l_Check_Value))
    {
        return String.Empty;
    }
}