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

时间:2016-07-06 17:07:10

标签: c# generics

我有一个用于管理物理量的通用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定义一个空的派生类(这很多),这使得我在组合分类中不灵活(不能转换{{1转到Quantity<ElektricResistanceUnit>)。

有人知道更优雅的解决方法吗?

1 个答案:

答案 0 :(得分:0)

我能看到的唯一避免空类的方法是做类似的事情:

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

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