比较 T 类型的两个 System.Enum

Compare two System.Enum of type T

我现在非常接近理解泛型(我认为)。
但是,只是认为 System.Enum 作为泛型类型实现起来并不容易。 我有这个 class:

public class Button<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable {
   public TEnum Identifier {
        get;
        private set; //Set in the ctor
    }
}

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;
    }
}

InputDevice 可能看起来像这样:

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

编译器在此处抛出编译错误:

if(button.Identifier == Identifier) //In AbstractInputDevice above

我相信我无法比较这两个 TEnum,因为它们实际上并不知道是枚举。
因此没有可用的比较方法。

我使用了这个资源:
Create Generic method constraining T to an Enum

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

您正在尝试对值类型(结构)执行引用比较,请使用 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;
}

无法执行button.Identifier == Identifier语句,因为结构不存在==运算符。在 class 上,它会执行参考比较。

正如@JeppeStigNielsen 在他的 中指出的那样,为防止装箱相等比较,最好使用 EqualityComparer<TEnum>.Default.Equals 方法。

而不是不可能

button.Identifier == Identifier

你应该使用

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

这避免了将值装入 object 框(或 IComparable 框)。