我创建了两个枚举,我知道它们不是相同但我认为它们是相等是有道理的,因为它们的字符串表示以及它们的数字表示是相等的(甚至相同......)。
换句话说:我希望第一个测试通过而第二个测试失败。但实际上,它们都失败了。那么:C#中的两个枚举何时相等?或者无论如何在C#中定义equals运算符?
谢谢!
public enum enumA {one, two}
public enum enumB {one, two}
[Test]
public void PreTest()
{
Assert.AreEqual(enumA.one,enumB.one);
Assert.AreSame(enumA.one, enumB.one);
}
更新:1)所以到目前为止所有答案都比较了表示,无论是整数还是字符串。 enum 本身总是不平等我聚集在一起?没有办法为它定义平等吗?
答案 0 :(得分:14)
枚举是在C#中强类型的,因此enumA.one != enumB.one
。现在,如果你将每个枚举转换为它们的整数值,它们将是相等的。
Assert.AreEqual((int)enumA.one, (int)enumB.one);
另外,我想挑战这句话,因为它们具有相同的整数或字符串表示,它们应该相同或等于。给定两个枚举NetworkInterface
和VehicleType
,对于C#或.Net Framework来说,当作为枚举进行比较时,允许NetworkInterface.None
等于VehicleType.None
是不合逻辑的。串。但是,如果开发人员将强类型枚举强制转换为整数或字符串,则语言或框架无法阻止二者进行等式。
为了进一步说明,您不能覆盖MyEnum.Equals
以提供不同的相等方法。 .Net枚举不是他们在Java的更高版本中的第一类公民,我希望C#允许与Enums进行更丰富的交互。
答案 1 :(得分:3)
我推荐您使用C#语言规范v3.0,该引用摘自第29页的Enum部分:
“每个枚举类型都有一个相应的整数类型,称为枚举类型的基础类型。未明确声明基础类型的枚举类型具有基础类型int。枚举类型的存储格式和可能值的范围是由其基础类型确定。枚举类型可以采用的值集不受其枚举成员的限制。特别是,枚举的基础类型的任何值都可以强制转换为枚举类型,并且是一个独特的有效值那个枚举类型。“
.AreEqual方法实际上测试的是等价,而第二个测试身份。因此,只需将每个类型转换为其基础类型(在本例中为int),然后进行比较。
public enum enumA { one, two }
public enum enumB { one, two }
[Test]
public void PreTest()
{
Assert.AreEqual((int)enumA.one,(int)enumB.one);
Assert.AreSame(enumA.one, enumB.one);
}
答案 2 :(得分:2)
与Java不同,C#不提供任何将方法(例如operator ==())添加到枚举的工具。
我在过去需要更智能的枚举时所做的是创建一个XHelper
类(其中X
是枚举的名称),我将所有方法都放在其上。因此这样的事情:
public static bool EnumAHelper.EqualsEnumB(EnumA enumA, EnumB enumB)
{
return (int)enumA == (int)enumB;
}
尽管如此,我不记得遇到过需要两个不同枚举来表示同样事情的情况。
答案 3 :(得分:1)
如果您希望它们匹配,请将它们转换为int
Assert.AreEqual((int)enumA.one,(int)enumB.one);
会通过,因为它们都是第一个列出的。如果你想让它们匹配,因为它们都说“一”,那么你需要使用反射。
答案 4 :(得分:1)
说实话,大多数时候平等并不是直截了当的。
我倾向于创建一个实现IEqualityComparer(以及任何其他相等测试,例如IsSame())的助手类并使用它。
答案 5 :(得分:0)
public enum enumA {one = 1, two = 2}
public enum enumB {one = 1, two = 2}
[Test]
public void PreTest()
{
Assert.AreEqual((int)enumA.one, (int)enumB.one);
// I don't think this one will ever pass
Assert.AreSame(enumA.one, enumB.one);
}
答案 6 :(得分:0)
您可以尝试投射它们:
Assert.AreEqual((int)enumA.one, (int)enumB.one);