Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以为泛型类的特定版本重载运算符吗?_C#_Generics - Fatal编程技术网

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可以是不同的单位类型,而你忘记了在数量构造函数中使用单位参数。