There have been a lot of similar questions asked but all involve operands of same type or same generic type. This one in particular (How can I use a generic type parameter with an operator overload?) is close to what I am looking for but no answer or work-around.
Is it possible to do something like this for the ‘*’ operator overload:
public class MyNumericClass<T>
{
public double Value { get; set; }
//OK but works only for same type operands
public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right)
{
return left.Value * right.Value;
}
//****Pseudo Code for different type operands - not OK****
public static double operator *<TRight>(MyNumericClass<T> left, MyNumericClass<TRight> right)
{
return left.Value * right.Value;
}
static void Test()
{
MyNumericClass<int> i = new MyNumericClass<int>();
MyNumericClass<int> j = new MyNumericClass<int>();
MyNumericClass<string> s = new MyNumericClass<string>();
double r1 = i * j;
double r2 = i * s; //Operator '*' cannot be applied to operands...
}
}
I need to have a specific overload for different generic types. A non-generic superclass will not do in this case as I have other overloads of the operator (not shown here) and ambiguous calls will be produced if I use a parameter of superclass type and not the exact generic type.
Is it possible to do this or is there a work-around? Is it possible to use op_Multiply instead? (Tried it but couldn’t make it work).
P.S. I don’t see any reason why something like this should not be possible.
EDIT1 After people's answers and comments I am adding another version of the class with the implicit casts and more overloads to demonstrate the call ambiguity and why the answers provided do not solve my problem. I need to specify the different generic type in my operator overload to resolve this:
public class MyNumericClass<T>
{
public double Value { get; set; }
public static implicit operator double(MyNumericClass<T> value)
{
return value.Value;
}
public static implicit operator MyNumericClass<T>(double value)
{
MyNumericClass<T> c = new MyNumericClass<T>();
c.Value = value;
return c;
}
public static MyNumericClass<T> operator *(double left, MyNumericClass<T> right)
{
return left * right.Value;
}
public static MyNumericClass<T> operator *(MyNumericClass<T> left, double right)
{
return right * left;
}
//Does not resolve ambiguity and neither does a base class or interface
public static double operator *(MyNumericClass<T> left, dynamic right)
{
return right * left;
}
//OK but work only for same type operands
public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right)
{
return left.Value * right.Value;
}
////****Pseudo Code for different type operands - not OK****
//public static double operator *<TRight>(MyNumericClass<T> left, MyNumericClass<TRight> right)
//{
// return left.Value * right.Value;
//}
static void Test()
{
MyNumericClass<int> i = new MyNumericClass<int>();
MyNumericClass<int> j = new MyNumericClass<int>();
MyNumericClass<string> s = new MyNumericClass<string>();
double r1 = i * j;
double r2 = i * s; //The call is ambiguous...
}
}
You might need to do it like this
It really depends on how you want to use it in the future.
You can either:
Make a non-generic base class which contains Value. The operator then works on the base class.
Implement an interface and use covariance.
Like this: