Search code examples
c#genericsenumscomparison

Compare two System.Enum of type T


I just figured out that System.Enum is not easy to implement as a generic type. The compiler throws an error when comparing two enums of type T:

if(button.Identifier == Identifier) // (in AbstractInputDevice)

I believe I cannot compare these two Enums because they are not actually known to be Enums. And thus no comparison method is available. How do I compare them for equality?

Here are more details:

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

and

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

An InputDevice might look like that:

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

I used this resource:
Create Generic method constraining T to an Enum


Solution

  • Instead of the impossible

    button.Identifier == Identifier
    

    you should use

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

    This avoids boxing the value into an object box (or IComparable box).