I am trying to build a wrapper class to store any enum. It should then be able to compare 2 different wrapper of different enum types.
public class SmartEnum<TEnum> where TEnum : System.Enum
{
public TEnum Enum;
public SmartEnum(TEnum Enum)
{
this.Enum = Enum;
}
public bool Equals(SmartEnum<TEnum> smartEnum)
{
var aType = Enum.GetType();
var bType = smartEnum.Enum.GetType();
if(aType != bType)
return false;
return (int)(object)(Enum) == (int)(object)(smartEnum.Enum);
}
}
The problem is that when I call the Equals method on enum A and pass enum B it defauls to using object.Equals instead:
SmartEnum<Color> red = new SmartEnum<Color>(Color.RED);
SmartEnum<Color> green = new SmartEnum<Color>(Color.GREEN);
SmartEnum<Car> car = new SmartEnum<Car>(Car.SUZUKI);
red.Equals(green); <-- Works
red.Equals(car) <-- Actually calls object.Equals
I understand that because SmartEnum is generic and Equals is not, it expects to receive the same type as the class instance.
If anyone knows how to do it or has a better way to compare different enums I would appreciate it :)
I tried to play around making it Equals<SmartEnum>
or Equals<T>
and use "where TEnum : SmartEnum but I can't seem to wrap my head around how to make this work:
1.
public bool Equals<T>(T smartEnum) where T : SmartEnum<TEnum>
This results in:
The type 'SmartEnum<SmartEnumTestUnit.Car>' cannot be used as type parameter 'T' in the generic type or method 'SmartEnum<SmartEnumTestUnit.Color>.Equals<T>(T)'. There is no implicit reference conversion from 'SmartEnum<SmartEnumTestUnit.Car>' to 'SmartEnum<SmartEnumTestUnit.Color>'
public bool Equals<SmartEnum>(SmartEnum<TEnum> smartEnum) where SmartEnum : SmartEnum<TEnum>
This results in defaulting to object.Equals
3.
public bool Equals<T>(T smartEnum) where T : TEnum
Finally results in:
red.Equals<Car>(car)
The type 'SmartEnumTestUnit.Car' cannot be used as type parameter 'T' in the generic type or method 'SmartEnum<SmartEnumTestUnit.Color>.Equals<T>(T)'. There is no boxing conversion from 'SmartEnumTestUnit.Car' to 'SmartEnumTestUnit.Color'.
Not sure why you want to do this, but one of the attempts was quite close, purely from technical perspective try the following:
public bool Equals<T>(SmartEnum<T> smartEnum) where T:Enum
{
// ...
}
This declares Equals
with generic parameter T
which should be enum and restricts the incoming smartEnum
parameter to SmartEnum<T>
.
Note that T
here just a generic parameter name, as SmartEnum
in:
public bool Equals<SmartEnum>(SmartEnum<TEnum> smartEnum) where SmartEnum : SmartEnum<TEnum>
Which results in quite interesting behavior here due to names matching (SmartEnum
in Equals<SmartEnum>
and where SmartEnum :
is parameter name, SmartEnum
in SmartEnum<TEnum> smartEnum
and : SmartEnum<T
is the enclosing generic type)
But in general you might want to override object.Equals(object)
and possibly implement IEquatable<SmartEnum<TEnum>>
.