C# 比较两个类型为T的系统枚举

C# 比较两个类型为T的系统枚举,c#,generics,enums,comparison,C#,Generics,Enums,Comparison,(我想)我现在已经非常了解泛型了。 然而,我们刚刚发现System.Enum不容易作为泛型类型实现。 我有这门课: public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable { public TEnum Identifier { get; private set; //Set in the ctor } } 我相信我不

(我想)我现在已经非常了解泛型了。
然而,我们刚刚发现System.Enum不容易作为泛型类型实现。 我有这门课:

public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
   public TEnum Identifier {
        get;
        private set; //Set in the ctor
    }
}
我相信我不能比较这两个十周年纪念日,因为他们实际上并不知道是枚举
因此没有可用的比较方法。

我使用了此资源:

我感谢任何更好的解决方案或修复方法。

(但我想将枚举项保留为
GetButton(EnumEntry)
)的一个参数。

如果您试图对值类型(struct)执行引用比较,请改用
Equals
表示相等:

public Button<TEnum> GetButton(TEnum Identifier) {
    var button = _buttons
        .Where(b => EqualityComparer<TEnum>.Default.Equals(b.Identifier, Identifier))
        .FirstOrDefault();

    if (button == null)
        Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
    return button;
}
public按钮GetButton(TEnum标识符){
var按钮=_按钮
.Where(b=>EqualityComparer.Default.Equals(b.Identifier,Identifier))
.FirstOrDefault();
如果(按钮==null)
Debug.Log(“““+GetType().Name+””不能返回未注册的“+typeof(Button).Name+”,它侦听“+typeof(TEnum).Name+”+“+Identifier.ToString()+”;
返回按钮;
}
无法执行
按钮.Identifier==Identifier
语句,因为结构不存在
=
运算符。在类上,它将执行引用比较


正如@JeppeStigNielsen在他的著作中所指出的,为了防止拳击平等性比较,最好使用
EqualityComparer.Default.Equals
方法

button.Identifier == Identifier
你应该使用

EqualityComparer<TEnum>.Default.Equals(button.Identifier, Identifier)
EqualityComparer.Default.Equals(button.Identifier,Identifier)

这避免了将值装箱到
对象
框(或
i可比较
框)。

编译器给您的确切错误是什么?您可能希望尝试
按钮.Identifier.Equals(Identifier)
,并使内容更简洁:
var按钮=\u按钮。其中(b=>b.Identifier.Equals(Identifier)).FirstOrDefault()@RonBeyer我使用Unity3D,他们的编译器有时会有点混乱。现在它会说“意外的符号“==”,好像会有打字错误。但是在做一些修改之前,它说一些不同的东西,比如“'==”不能应用于'TEnum'和'TEnum'类型的操作数。我想说你需要做一个@Alex,你是serius吗?没有错误了!.Equals()按照注释中的说明工作。但是我不明白我应该如何实现你在我的if语句中发布的这一新行…@NoelWidmer在你原来的
GetButton
方法的上下文中添加了它?如果是,您知道它在哪个命名空间中吗?(它不被识别为_按钮的成员)@NoelWidmer是的,您需要使用System.Linq添加
声明确实-我知道。非常感谢你!这将是一个更好的比较,agreedAlright,因为Alex同意这个解决方案(我已经将他的答案标记为),所以我将改为标记这个。@NoelWidmer您仍然可以使用Linq
\u按钮。FirstOrDefault(b=>EqualityComparer.Default.Equals(b.Identifier,Identifier))
就像Alex建议的那样,但这更多的是风格和个人偏好的问题。有趣的是,
EqualityComparer(属于枚举类型)。默认值
避免了装箱,因为枚举类型不实现
IEquatable(自身)
。我想知道
EqualityComparer(of T)。除了
IEquatable
,Default
还查找什么?@supercat只需查看
的运行时类型。Default
实例提供了一些线索。对于枚举类型
E
,我得到
System.Collections.Generic.EnumEqualityComparer`1[E]
,因此存在对枚举的特殊支持。考虑到这一点,他们当然很小心,避免了拳击。对于实现
IEquatable`1[G]
的结构
G
,我得到
System.Collections.Generic.GenericEqualityComparer`1[G]
。最后,对于没有泛型相等支持的结构
N
,我得到
System.Collections.generic.ObjectEqualityComparer`1[N]
。添加:使用.NET4.5.2。
public Button<TEnum> GetButton(TEnum Identifier) {
    var button = _buttons
        .Where(b => EqualityComparer<TEnum>.Default.Equals(b.Identifier, Identifier))
        .FirstOrDefault();

    if (button == null)
        Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
    return button;
}
button.Identifier == Identifier
EqualityComparer<TEnum>.Default.Equals(button.Identifier, Identifier)