如何用泛型类的不同泛型类型的操作数重载泛型类的运算符

本文关键字:泛型类 操作数 重载 运算符 泛型类型 何用 | 更新日期: 2023-09-27 18:28:17

有很多类似的问题,但都涉及相同类型或相同泛型类型的操作数。特别是这一个(如何使用带有运算符重载的泛型类型参数?)与我想要的很接近,但没有答案或解决方法。

有可能对"*"操作员过载做这样的事情吗:

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...
    }
}

我需要为不同的泛型类型指定一个特定的重载。在这种情况下,非泛型超类不会起作用,因为我有其他运算符重载(此处未显示),如果我使用超类类型的参数而不是确切的泛型类型,则会产生不明确的调用。

有可能做到这一点吗?或者周围有工作吗?是否可以使用op_Multiply?(试过了,但没能成功)。

附言:我看不出有什么理由不可能发生这样的事情。

编辑1在人们的回答和评论之后,我添加了另一个版本的类,其中包含隐式类型转换和更多重载,以演示调用的模糊性,以及为什么提供的答案不能解决我的问题。我需要在我的运算符重载中指定不同的泛型类型来解决这个问题:

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...
    }
}

如何用泛型类的不同泛型类型的操作数重载泛型类的运算符

这实际上取决于您将来希望如何使用它
您可以:

制作一个包含Value的非泛型基类。然后,操作符处理基类。

实现接口并使用协方差。

像这样:

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;
    }
}

您可能需要像这样做

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;
    }
}