Compare two types of System.Enum type T

I'm pretty close to Generics (I think).
However, I just thought 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; } } 

InputDevice might look like this:

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

The compiler throws a compilation error right here:

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

I believe that I can not compare these two TEnums, because in fact they are not known as Enums.
Therefore, the comparison method is not available.

I used this resource:
Create a generic method restricting T to Enum

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

+6
source share
2 answers

Instead of the impossible

 button.Identifier == Identifier 

you should use

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

This avoids boxing values ​​in the object (or IComparable ) field.

+10
source

You are trying to perform a reference comparison by value type (struct), use Equals instead of equality:

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

The button.Identifier == Identifier statement cannot be executed because the == operator does not exist for structures. In class, he would do a comparative comparison.

And as @JeppeStigNielsen noted in his answer, in order to prevent comparison of boxing equality, it is better to use the EqualityComparer<TEnum>.Default.Equals .

+1
source

Source: https://habr.com/ru/post/986187/


All Articles