Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare two System.Enum of type T

I am pretty close to understand Generics now (I think).
However, just figured that System.Enum is not easy to implement as a generic type. I have this class:

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

The compiler throws a compile error right here:

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

I believe I cannot compare these two TEnums because they are not actually known to be Enums.
And thus no comparison method is available.

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

I appreciate any better solution or fix.
(But I want to keep the Enum entry as a parameter to GetButton(EnumEntry))

like image 350
Noel Widmer Avatar asked Apr 28 '15 20:04

Noel Widmer


People also ask

Can you use == for enum?

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

Can we compare enum with INT?

Any int (or matched intergral type if the enum base is changed) may be cast to that enum. This answer implies that there will be an exception if i1 is 10, for example.

How do you know if enums are equal?

equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.


1 Answers

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).

like image 133
Jeppe Stig Nielsen Avatar answered Oct 24 '22 18:10

Jeppe Stig Nielsen