How to overload a generalized class operator with operands of different generic types of a general class

Many identical questions were asked, but they all include operands of the same type or of the same type. This, in particular, ( How can I use a type parameter with operator overloading? ) Is close to what I'm looking for, but not responding or getting around.

Is it possible to do something like this to overload the '* operator:

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 a specific overload for different types. An unnecessary superclass will not do in this case, since I have other operator overloads (not shown here), and ambiguous calls will be received if I use the superclass type parameter, and not the exact generic type.

Can this be done or is there a workaround? Can op_Multiply be used instead? (I tried, but could not get it to work).

PS I see no reason why something like this should not be possible.

EDIT1 After people respond and comment, I add another version of this class with implicit clicks and lots of overloads to demonstrate the ambiguity of the call and why the answers do not solve my problem. I need to specify a different generic type in my operator overload to solve this problem:

 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... } } 
0
source share
2 answers

It really depends on how you want to use it in the future.
You can:

Create a non-generic template class containing the value. Then the operator works on the base class.

Implement an interface and use covariance.

Like this:

 void Main() { 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; } public interface IMyNumericClass<out T> { double Value { get; set; } } public class MyNumericClass<T> : IMyNumericClass<T> { public double Value { get; set; } public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right) { return left.Value * right.Value; } public static double operator *(MyNumericClass<T> left, IMyNumericClass<object> right) { return left.Value * right.Value; } } 
+1
source

You may need to do this as

 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<double> right) { return left.Value * right.Value; } public static double operator *(MyNumericClass<T> left, MyNumericClass<T> right) { return left.Value * right.Value; } static void Test() { MyNumericClass<int> i = new MyNumericClass<int>(); MyNumericClass<int> i2 = new MyNumericClass<int>(); MyNumericClass<double> j = new MyNumericClass<double>(); double r1 = i * i2; double r2 = i * j; } } 
0
source

Source: https://habr.com/ru/post/977339/


All Articles