C# 枚举等于() vs ==

本文关键字:vs 枚举 | 更新日期: 2023-09-27 18:21:16

在使用枚举的情况下,使用

if (enumInstance.Equals(MyEnum.SomeValue))

或使用

if (enumInstance == MyEnum.SomeValue)

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

C# 枚举等于() vs ==

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

如果enumInstance的编译时类型是EnumValueTypeObject,则需要使用Equals。(在这种情况下尝试使用 ==,则会收到编译时错误。

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

使用 == 而不是 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:

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 指令,Equals 方法执行装箱和调用

作为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
    }
}

如果在测试应用中尝试以下操作,将得到以下结果

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

您将获得以下结果

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

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

其他方法都不起作用(包括价值。等于 (0(,值。等于((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;
    }
}
有一种

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

对于 c#,枚举的基础类型是积分。因为它是积分,所以你可以在逻辑上将枚举 OR 放在一起。

使用上述任一方法相等时,如果枚举在逻辑上是 OR 组合在一起,则相等将失败。

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

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

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

严格来说,将"=="与枚举一起使用是最安全的。

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