c# - 通用运算符的有效方法

标签 c# generics inheritance operator-keyword

我有一个类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)
    {
        ...
    }
}

完整的上下文如下:

  1. Gen<T>等于 ColorSet<T>其中 T:颜色
  2. 父级等于颜色
  3. 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/

相关文章:

css - 更少的继承不起作用

c# - IEnumerable 与 IQueryable 对象 - LinQ to SQL

java - Exchange Web 服务通过 "Message-ID" header 查找 EmailMessage

c# - 使用 Knockoutjs 显示点击的项目

java - 如何避免在子类中强制转换父级字段

c++ - 从派生类访问基类对象

c# - Visual Studio 2010 : How to enforce build order of projects in a solution?

c# - 如何区分泛型类中具有相同名称和参数个数的两个方法?

java - 冗余通用参数

java - protected 抽象方法在父类包装实例的子类中不可见