I have a class Gen<T> and I want to make it possible to compare them. The following code cannot be compiled, because the == cannot be applied to Parent and Child. Is there a way to make this comparison possible, or is this bad practice in general?
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)
{
...
}
}
The full context is the following:
Gen<T> equals ColorSet<T> where T:ColorI want to access every Color through the ColorSet<T> class, which looks like this:
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");
}
}
But sometimes I need ColorSet<Color> and sometimes ColorSet<Child> for the additional information. And it should be possible to compare ColorSet<Color> with ColorSet<Child> because they have the most relevant information in common.
(expanding from the comments) A generic class doesn't seem to be necessary. A valid approach for getting operators to work for generic types is to re-work the types so that they're no longer generic.
ColorSet could be defined as
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));
}
}
Instead of new ColorSet<ExtendedColor>(), you would now call ColorSet.FromType<ExtendedColor>().
This works so long as you don't actually need to use your T outside of your constructor.
If you had, for instance, a
public T Red { get { return red; } }
property, you would need to change that to a
public Color Red { get { return red; } }
property.
However, if you have anything like that, and you do want to keep the generic type, you can then put that in a derived generic class:
public class ColorSet<T> : ColorSet where T : Color {
public ColorSet<T>() : base(typeof(T)) { }
public new T Red { get { return (T)base.Red; } }
}
which still only needs operators for the base non-generic ColorSet class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With