比较不同的枚举在泛型<TEnum>类中

huangapple go评论91阅读模式
英文:

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&lt;TEnum&gt; 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&lt;Color&gt; red = new SmartEnum&lt;Color&gt;(Color.RED);
SmartEnum&lt;Color&gt; green = new SmartEnum&lt;Color&gt;(Color.GREEN);
SmartEnum&lt;Car&gt; car = new SmartEnum&lt;Car&gt;(Car.SUZUKI);

red.Equals(green); &lt;-- 正常工作
red.Equals(car) &lt;-- 实际上调用了 object.Equals

我理解,因为 SmartEnum&lt;TEnum&gt; 是泛型,而 Equals 不是,它期望接收与类实例相同的类型。

如果有人知道如何做或有更好的方法来比较不同的枚举,我会很感激 :)

我尝试了一些方法,比如将它变成 `Equals&lt;SmartEnum&gt;` 或 `Equals&lt;T&gt;`,并使用 "where TEnum : SmartEnum&lt;TEnum&gt; 但是我似乎无法弄清楚如何使其工作:

 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&lt;TEnum&gt; where TEnum : System.Enum
{
    public TEnum Enum;

    public SmartEnum(TEnum Enum)
    {
        this.Enum = Enum;
    }

    public bool Equals(SmartEnum&lt;TEnum&gt; 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&lt;Color&gt; red = new SmartEnum&lt;Color&gt;(Color.RED);
    SmartEnum&lt;Color&gt; green = new SmartEnum&lt;Color&gt;(Color.GREEN);
    SmartEnum&lt;Car&gt; car = new SmartEnum&lt;Car&gt;(Car.SUZUKI);
    
    red.Equals(green); &lt;-- Works
    red.Equals(car) &lt;-- 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 比较不同的枚举在泛型<TEnum>类中

I tried to play around making it Equals&lt;SmartEnum&gt; or Equals&lt;T&gt; and use "where TEnum : SmartEnum<TEnum> but I can't seem to wrap my head around how to make this work:

public bool Equals&lt;T&gt;(T smartEnum) where T : SmartEnum&lt;TEnum&gt;

This results in:

The type &#39;SmartEnum&lt;SmartEnumTestUnit.Car&gt;&#39; cannot be used as type parameter &#39;T&#39; in the generic type or method &#39;SmartEnum&lt;SmartEnumTestUnit.Color&gt;.Equals&lt;T&gt;(T)&#39;. There is no implicit reference conversion from &#39;SmartEnum&lt;SmartEnumTestUnit.Car&gt;&#39; to &#39;SmartEnum&lt;SmartEnumTestUnit.Color&gt;&#39;
public bool Equals&lt;SmartEnum&gt;(SmartEnum&lt;TEnum&gt; smartEnum) where SmartEnum : SmartEnum&lt;TEnum&gt;

This results in defaulting to object.Equals

3.

public bool Equals&lt;T&gt;(T smartEnum) where T : TEnum

Finally results in:

red.Equals&lt;Car&gt;(car) 
The type &#39;SmartEnumTestUnit.Car&#39; cannot be used as type parameter &#39;T&#39; in the generic type or method &#39;SmartEnum&lt;SmartEnumTestUnit.Color&gt;.Equals&lt;T&gt;(T)&#39;. There is no boxing conversion from &#39;SmartEnumTestUnit.Car&#39; to &#39;SmartEnumTestUnit.Color&#39;.

答案1

得分: 2

不确定为什么您要这样做,但从技术角度来看,以下是一种接近的尝试:

```csharp
public bool Equals&lt;T&gt;(SmartEnum&lt;T&gt; smartEnum) where T:Enum
{
    // ...
}

这声明了一个带有泛型参数TEquals方法,其中T应该是枚举,并限制了传入的smartEnum参数为SmartEnum&lt;T&gt;

请注意,这里的T只是一个泛型参数名称,就像在下面的代码中一样:

public bool Equals&lt;SmartEnum&gt;(SmartEnum&lt;TEnum&gt; smartEnum) where SmartEnum : SmartEnum&lt;TEnum&gt;

由于名称匹配(Equals&lt;SmartEnum&gt;where SmartEnum :中的SmartEnum是参数名称,在SmartEnum&lt;TEnum&gt; smartEnum中的SmartEnum&lt;T是封闭的泛型类型),这会导致相当有趣的行为。

但总的来说,您可能希望重写object.Equals(object)方法,并可能实现IEquatable&lt;SmartEnum&lt;TEnum&gt;&gt;


<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&lt;T&gt;(SmartEnum&lt;T&gt; smartEnum) where T:Enum
{
    // ...
}

This declares Equals with generic parameter T which should be enum and restricts the incoming smartEnum parameter to SmartEnum&lt;T&gt;.

Note that T here just a generic parameter name, as SmartEnum in:

public bool Equals&lt;SmartEnum&gt;(SmartEnum&lt;TEnum&gt; smartEnum) where SmartEnum : SmartEnum&lt;TEnum&gt;

Which results in quite interesting behavior here due to names matching (SmartEnum in Equals&lt;SmartEnum&gt; and where SmartEnum : is parameter name, SmartEnum in SmartEnum&lt;TEnum&gt; smartEnum and : SmartEnum&lt;T is the enclosing generic type)

But in general you might want to override object.Equals(object) and possibly implement IEquatable&lt;SmartEnum&lt;TEnum&gt;&gt;.

huangapple
  • 本文由 发表于 2023年6月29日 02:57:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76575987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定