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

时间:2015-04-28 20:40:25

标签: 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
    }
}

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

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

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

我感谢任何更好的解决方案或修复 (但我希望将Enum条目作为GetButton(EnumEntry))的参数

2 个答案:

答案 0 :(得分:13)

而不是不可能的

button.Identifier == Identifier

你应该使用

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

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

答案 1 :(得分:1)

您正尝试对值类型(struct)执行引用比较,而是使用newtype Poly a = P [a] x :: Num a => Poly a chop :: (Eq a, Num a) => Poly a -> Poly a chop (P l) = if (last l) == 0 then chop (P $ init l) else P l instance (Num a, Eq a) => Eq (Poly a) where (==) m n = if (chop m) == (chop n) then True else False 代替相等:

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运算符。在课堂上,它会进行参考比较。

正如@JeppeStigNielsen在answer中指出的那样,为了防止拳击平等比较,最好使用==方法。