我有一个 Gen<T> 类,我想让比较它们成为可能。以下代码无法编译,因为 == 不能应用于 Parent 和 Child。有没有办法使这种比较成为可能,或者一般来说这是不好的做法?

public class Parent{
    public int x;
}

public class Child:Parent{}

public class Gen<T>
    where T : Parent
{
    public T variable;
}

public static class Gen
{
    public static bool operator ==(Gen<Parent> left, Gen<Parent> right){
        if (left.variable.x == right.variable.x)
            return true;
        else
            return false;
    }
}

public void Test()
{
    Gen<Parent> foo = new Gen<Parent>();
    Gen<Child> bar = new Gen<Child>();

    if (foo == bar)
    {
        ...
    }
}

完整的上下文如下:
  • Gen<T> 等于 ColorSet<T> 其中 T:Color
  • 父级等于颜色
  • Child 是一个类,用于存储颜色的附加信息,并不是每个 Color 对象都需要这些信息。

  • 我想通过 Color 类访问每个 ColorSet<T>,它看起来像这样:
    public class ColorSet<T> where T : Color
    {
         private T blue;
         private T red;
         private T green;
    
         public ColorSet()
         {
             Red = (T)Activator.CreateInstance(typeof(T), new object[] { });
             Red.Name = Values.Res.get("red");
             Blue = (T)Activator.CreateInstance(typeof(T), new object[] { });
             Blue.Name = Values.Res.get("blue");
             Green = (T)Activator.CreateInstance(typeof(T), new object[] { });
             Green.Name = Values.Res.get("green");
         }
    }
    

    但有时我需要 ColorSet<Color> ,有时需要 ColorSet<Child> 来获取附加信息。并且应该可以将 ColorSet<Color>ColorSet<Child> 进行比较,因为它们具有最相关的共同信息。

    最佳答案

    (从评论中扩展)泛型类似乎没有必要。让运算符适用于泛型类型的有效方法是重新处理类型,使它们不再是泛型。
    ColorSet 可以定义为

    public class ColorSet {
      private Color red;
      private Color green;
      private Color blue;
    
      protected ColorSet(Type type) {
        red = (Color)Activator.CreateType(type);
        red.Name = Values.Res.get("red");
        green = (Color)Activator.CreateType(type);
        green.Name = Values.Res.get("red");
        blue = (Color)Activator.CreateType(type);
        blue.Name = Values.Res.get("red");
      }
    
      public static ColorSet FromType<T>() where T : Color {
        return new ColorSet(typeof(T));
      }
    }
    

    您现在可以调用 new ColorSet<ExtendedColor>() 而不是 ColorSet.FromType<ExtendedColor>()

    只要您实际上不需要在构造函数之外使用 T,此方法就有效。

    例如,如果你有一个
    public T Red { get { return red; } }
    

    属性,您需要将其更改为
    public Color Red { get { return red; } }
    

    属性(property)。

    但是,如果您有类似的东西,并且确实想保留泛型类型,则可以将其放入派生的泛型类中:
    public class ColorSet<T> : ColorSet where T : Color {
      public ColorSet<T>() : base(typeof(T)) { }
      public new T Red { get { return (T)base.Red; } }
    }
    

    它仍然只需要基本非通用 ColorSet 类的运算符。

    关于c# - 通用运算符的有效方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25398208/

    10-11 23:58