在使用枚举的情况下,最好使用:
if (enumInstance.Equals(MyEnum.SomeValue))
或使用
if (enumInstance == MyEnum.SomeValue)
他们的任何重要考虑因素都是使用一对吗?
答案 0 :(得分:50)
如果enumInstance
的编译时类型是枚举类型,则可以使用==
。
如果enumInstance
的编译时类型为Enum
,ValueType
或Object
,则需要使用Equals
。 (如果在这种情况下尝试使用==
,则会出现编译时错误。)
请注意,您的枚举当前违反了.NET命名约定 - 通常为MyEnum.Value
。
答案 1 :(得分:25)
使用==而不是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方法执行拳击和callvirt
答案 2 :(得分:1)
有一种情况是,这里的其他答案没有提到可以帮助他人。
使用c#,枚举的基础类型是一个整数。因为它是不可或缺的,所以你可以将枚举逻辑OR在一起。
如果枚举在逻辑上与OR一起使用,则使用上述任何一种方法进行相等操作都会失败。
因此,对于某些特殊情况,例如使用枚举作为标志,在检查相等性之前,您需要首先逻辑地判断您正在测试的情况。
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
答案 3 :(得分:-1)
作为Jon Skeet旧答案的扩展,比较Enum == YourActualEnum.Value
时会出现编译错误,但是当你Enum == Enum
执行编译时,它会返回一直都是假的。
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
如果你想知道为什么要将Enum与Enum进行比较......我在为WPF项目创建EnumConverter和FlagConvert时尝试变聪明时发现了它。在那里你只收到一个对象值作为参数,对于标志转换器,我特别希望在没有选择标志时提供一个特殊的文本(即enum的值为0,没有静态成员)。
除此之外没有其他工作(包括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;
}
}