比较两个类型为T的System.Enum

Noe*_*mer 8 c# generics comparison enums

我现在非常接近了解Generics(我认为).
但是,只是认为System.Enum不容易实现为泛型类型.我有这门课:

public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
   public TEnum Identifier {
        get;
        private set; //Set in the ctor
    }
}
Run Code Online (Sandbox Code Playgroud)

public abstract class AbstractInputDevice<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {

   private List<Button<TEnum>> _buttons = new List<Button<TEnum>>();

   public Button<TEnum> GetButton(TEnum Identifier){
        foreach(Button<TEnum> button in _buttons){
            if(button.Identifier == Identifier) //<- compiler throws
                return button;
        }
        Debug.Log("'" + GetType().Name + "' cannot return an <b>unregistered</b> '" + typeof(Button<TEnum>).Name + "' that listens to '" + typeof(TEnum).Name + "." + Identifier.ToString() + "'.");
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

InputDevice可能看起来像这样:

public class Keyboard : AbstractInputDevice<KeyCode> {
    private void Useless(){
        Button<KeyCode> = GetButton(KeyCode.A);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器在这里抛出一个编译错误:

if(button.Identifier == Identifier) //In AbstractInputDevice above
Run Code Online (Sandbox Code Playgroud)

我相信我无法比较这两个TEnums,因为它们实际上并不是Enums.
因此没有比较方法可用.

我使用了这个资源:
创建将T限制为枚举的通用方法

我感谢任何更好的解决方案或修复.
(但我想将Enum条目保留为参数GetButton(EnumEntry))

Jep*_*sen 13

而不是不可能的

button.Identifier == Identifier
Run Code Online (Sandbox Code Playgroud)

你应该使用

EqualityComparer<TEnum>.Default.Equals(button.Identifier, Identifier)
Run Code Online (Sandbox Code Playgroud)

这可以避免将值装入object框(或IComparable框).

  • @supercat简单地查看`.Default`实例的运行时类型给出了一些线索.对于枚举类型`E`,我得到``System.Collections.Generic.EnumEqualityComparer`1 [E]``,因此存在对枚举的特殊支持.鉴于此,他们肯定会照顾并避免拳击.对于实现``IEquatable`1 [G]``的struct`G`,我得到``System.Collections.Generic.GenericEqualityComparer`1 [G]``.最后,对于没有通用相等支持的结构`N`,我得到``System.Collections.Generic.ObjectEqualityComparer`1 [N]``.***添加:***使用.NET 4.5.2. (2认同)