英文:
Comparing different Enums in generic <TEnum> class
问题
我试图构建一个包装类来存储任何枚举。然后,它应该能够比较两个不同枚举类型的不同包装。
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);
}
}
问题是,当我调用枚举 A 上的 Equals 方法并传递枚举 B 时,它默认使用 object.Equals:
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); <-- 正常工作
red.Equals(car) <-- 实际上调用了 object.Equals
我理解,因为 SmartEnum<TEnum> 是泛型,而 Equals 不是,它期望接收与类实例相同的类型。
如果有人知道如何做或有更好的方法来比较不同的枚举,我会很感激 :)
我尝试了一些方法,比如将它变成 `Equals<SmartEnum>` 或 `Equals<T>`,并使用 "where TEnum : SmartEnum<TEnum> 但是我似乎无法弄清楚如何使其工作:
1.
public bool Equals<T>(T smartEnum) where T : SmartEnum<TEnum>
结果是:
类型 'SmartEnum<SmartEnumTestUnit.Car>' 无法用作泛型类型或方法 'SmartEnum<SmartEnumTestUnit.Color>.Equals<T>(T)' 的类型参数 'T'。没有从 'SmartEnum<SmartEnumTestUnit.Car>' 到 'SmartEnum<SmartEnumTestUnit.Color>' 的隐式引用转换。
2.
public bool Equals<SmartEnum>(SmartEnum<TEnum> smartEnum) where SmartEnum : SmartEnum<TEnum>
这将默认为 object.Equals
3.
public bool Equals<T>(T smartEnum) where T : TEnum
最后的结果是:
red.Equals<Car>(car)
类型 'SmartEnumTestUnit.Car' 无法用作泛型类型或方法 'SmartEnum<SmartEnumTestUnit.Color>.Equals<T>(T)' 的类型参数 'T'。没有从 'SmartEnumTestUnit.Car' 到 'SmartEnumTestUnit.Color' 的装箱转换。
英文:
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<TEnum> 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<TEnum> but I can't seem to wrap my head around how to make this work:
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'.
答案1
得分: 2
不确定为什么您要这样做,但从技术角度来看,以下是一种接近的尝试:
```csharp
public bool Equals<T>(SmartEnum<T> smartEnum) where T:Enum
{
// ...
}
这声明了一个带有泛型参数T
的Equals
方法,其中T
应该是枚举,并限制了传入的smartEnum
参数为SmartEnum<T>
。
请注意,这里的T
只是一个泛型参数名称,就像在下面的代码中一样:
public bool Equals<SmartEnum>(SmartEnum<TEnum> smartEnum) where SmartEnum : SmartEnum<TEnum>
由于名称匹配(Equals<SmartEnum>
和where SmartEnum :
中的SmartEnum
是参数名称,在SmartEnum<TEnum> smartEnum
中的SmartEnum<T
是封闭的泛型类型),这会导致相当有趣的行为。
但总的来说,您可能希望重写object.Equals(object)
方法,并可能实现IEquatable<SmartEnum<TEnum>>
。
<details>
<summary>英文:</summary>
Not sure why you want to do this, but one of the attempts was quite close, purely from technical perspective try the following:
```csharp
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>>
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论