我可以为泛型类的特定版本重载运算符吗?

本文关键字:重载 运算符 版本 泛型类 我可以 | 更新日期: 2023-09-27 17:55:16

我有一个用于管理物理量的通用Quantity<T>类,看起来像这样:

public class Quantity<T> where T : Unit
{
    public Quantity(double value, T unit)
    {
        this.OriginalUnit = unit;
        this.Value = unit.ConvertBack(value);
    }
...
}

Unit类管理数量可以采用的不同单位,但这与我的问题并不真正相关。

我想做的是在泛型Quantity<T>类中定义运算符,如下所示:

    public static Quantity<ElectricResistanceUnit> operator /
        (Quantity<ElectricVoltageUnit> q1, Quantity<ElectricCurrentUnit> q2)
    {
        return new Quantity<ElectricResistanceUnit>(q1.Value / q2.Value, ElectricResistanceUnit.Ohm);
    }

但这不会编译("二进制运算符的参数之一必须是包含类型")。有什么办法吗?

一种工作方式,对我来说并不是真正的解决方案,如下:

public class ElectricVoltage : Quantity<ElectricVoltageUnit>
{
    public static ElectricResistance operator /(ElectricVoltage q1, ElectricCurrent q2)
    {
        return new ElectricResistance(q1.Value / q2.Value, ElectricResistanceUnit.Ohm);
    }
}
public class ElectricCurrent : Quantity<ElectricCurrentUnit>
{
}
public class ElectricResistance : Quantity<ElectricResistanceUnit>
{
}

这样做的问题是:我必须为我的所有Unit定义一个空的派生类(这是一个 LOT),而且这使我在组合类中变得不灵活(不能将Quantity<ElektricResistanceUnit>转换为ElectricResistance)。

有人知道解决这个问题的更优雅的方法吗?

我可以为泛型类的特定版本重载运算符吗?

我可以看到,在您的情况下避免空类的唯一方法是执行以下操作:

interface INumeric<T>
{
    T Add(T num);
    T Substract(T num);
    T Multiply(T num);
    T Divide(T num);
}
class Quantity<T> where T : INumeric<T>
{
    public T Value { get; set; }
    public static Quantity<T> operator + (Quantity<T> left, Quantity<T> right) 
    {
        return new Quantity<T>() { Value = left.Value.Add(right.Value) };
    }
    public static Quantity<T> operator - (Quantity<T> left, Quantity<T> right) 
    {
        return new Quantity<T>() { Value = left.Value.Substract(right.Value) };
    }
    public static Quantity<T> operator / (Quantity<T> left, Quantity<T> right)
    {
        return new Quantity<T>() { Value = left.Value.Divide(right.Value) };
    }
    public static Quantity<T> operator * (Quantity<T> left, Quantity<T> right)
    {
        return new Quantity<T>() { Value = left.Value.Multiply(right.Value) };
    }
}

然后你必须在Unit中实现INumeric<T>,每个单元都可以有自己的方法实现