C# 我可以为泛型类的特定版本重载运算符吗?
我有一个通用的C# 我可以为泛型类的特定版本重载运算符吗?,c#,generics,C#,Generics,我有一个通用的Quantity类用于管理物理量,如下所示: public class Quantity<T> where T : Unit { public Quantity(double value, T unit) { this.OriginalUnit = unit; this.Value = unit.ConvertBack(value); } ... } public static Quantity<E
Quantity
类用于管理物理量,如下所示:
public class Quantity<T> where T : Unit
{
public Quantity(double value, T unit)
{
this.OriginalUnit = unit;
this.Value = unit.ConvertBack(value);
}
...
}
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>
{
}
公共级电压:数量
{
公共静电电阻操作器/(电压q1,电流q2)
{
返回新电阻(q1.Value/q2.Value,电阻单位:欧姆);
}
}
公共类电流:数量
{
}
公共级电阻:数量
{
}
这样做的问题是:我必须为我所有的单元
定义一个空的派生类(这是很多),而且这使得我在组合类中缺乏灵活性(不能将数量
转换为电阻
)
有人知道解决这个问题的更优雅的方法吗?在您的案例中,我看到避免空类的唯一方法是这样做:
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) };
}
}
接口输入法
{
T加(T数);
T减法(T num);
T乘(T num);
T除(T num);
}
类数量,其中T:单位
{
公共T值{get;set;}
公共静态数量运算符+(左数量、右数量)
{
返回新数量(){Value=left.Value.Add(right.Value)};
}
公共静态数量运算符-(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Substract(right.Value)};
}
公共静态数量运算符/(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Divide(right.Value)};
}
公共静态数量运算符*(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Multiply(right.Value)};
}
}
然后您必须在
单元中实现INumeric
,每个单元都可以有自己的方法实现在您的情况下,我看到避免空类的唯一方法是这样做:
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) };
}
}
接口输入法
{
T加(T数);
T减法(T num);
T乘(T num);
T除(T num);
}
类数量,其中T:单位
{
公共T值{get;set;}
公共静态数量运算符+(左数量、右数量)
{
返回新数量(){Value=left.Value.Add(right.Value)};
}
公共静态数量运算符-(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Substract(right.Value)};
}
公共静态数量运算符/(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Divide(right.Value)};
}
公共静态数量运算符*(左侧数量,右侧数量)
{
返回新数量(){Value=left.Value.Multiply(right.Value)};
}
}
然后你必须在Unit
中实现INumeric
,每个单元都可以有它自己的这种方法的实现我以前创建过这种精确的东西,我的方法是将任意尺寸表示为5个基本尺寸的有理幂:长度、质量、时间、温度和电流。因此,不是每个可能的组合都有一个不同的类,而是只有一个类代表一个量的维度。您仍然无法获得编译时安全性,但我想不出一种方法来强制实现这一点,而无需对每个维度组合进行硬编码。+您拥有的事实:要为操作传递一个单元实例,+3个不同的操作单元类型(至少如果两者都相同,则更容易找到解决方法),但就像现在一样,用一种通用的方式编写代码似乎真的很难。谢谢你的想法!我得出的结论是,这在泛型中可能是不可能的。因此,我现在不再使用泛型,而是使用T4模板为所有可用单位自动生成硬编码数量。这样我就可以拥有编译时类型安全性和我想要的所有操作符。我以前创建过这类东西,我的方法是将任意维度表示为5个基本维度的有理幂:长度、质量、时间、温度和电流。因此,不是每个可能的组合都有一个不同的类,而是只有一个类代表一个量的维度。您仍然无法获得编译时安全性,但我想不出一种方法来强制实现这一点,而无需对每个维度组合进行硬编码。+您拥有的事实:要为操作传递一个单元实例,+3个不同的操作单元类型(至少如果两者都相同,则更容易找到解决方法),但就像现在一样,用一种通用的方式编写代码似乎真的很难。谢谢你的想法!我得出的结论是,这在泛型中可能是不可能的。因此,我现在不再使用泛型,而是使用T4模板为所有可用单位自动生成硬编码数量。这样我就可以拥有编译时类型安全性和我想要的所有运算符。这是行不通的,因为t可以是不同的单位类型,而你忘记了在数量构造函数中使用单位参数。这是行不通的,因为t可以是不同的单位类型,而你忘记了在数量构造函数中使用单位参数。