c# - 帮助类里面的数学操作数 (c#)

标签 c# class operands

public class Racional<T>
{
    private T nominator;
    private T denominator;
    public T Nominator
    {
        get { return nominator; }
        set { nominator = value; }
    }
    public T Denominator
    {
        get { return denominator; }
        set { denominator = value; }
    }
    public Racional(T nominator, T denominator)
    {
        this.nominator = nominator;
        this.denominator = denominator;
    }
    public static Racional<int> operator *(Racional<int> a, Racional<int> b)
    {
        return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
    }
    public override string ToString()
    {
        return "(" + this.nominator + " " + this.denominator + ")";
    }
}

我对这部分感兴趣:

public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
    return ((int)(a.nominator + b.nominator,  a.denominator + b.denominator));
}

出了什么问题:

One of the parameters of a binary operator must be the containing type

我如何正常编写这部分代码以进行数学运算?

最佳答案

您的代码无法编译的原因是由编译器错误解释的。包含类型是泛型类型定义,从这种类型构造的泛型类型不被视为同一类型。

我有几个问题:

  1. 为什么 Rational 类型必须是通用的?有理数被定义为可以表示为两个整数(其中分母不是0)的商/分数的数字。为什么不使该类型成为非泛型类型并在整个过程中简单地使用 int 呢?或者您打算将该类型用于其他整数类型,例如 longBigInteger?在这种情况下,如果您需要某种代码共享机制,请考虑使用类似 Aliostad 的建议。
  2. 为什么您希望两个有理数的乘积等于它们的分子之和除以它们的分母之和?这对我来说没有意义。

在任何情况下,您似乎都希望能够“一般地”添加两个“可添加”类型的实例。遗憾的是,目前没有任何方法可以在 C# 中表达“具有合适的加法运算符”约束。

方法 #1:C# 4 中的一种解决方法是使用 dynamic 类型为您提供所需的“虚拟运算符”语义。

public static Racional<T> operator *(Racional<T> a, Racional<T> b)
{
    var nominatorSum = (dynamic)a.Nominator + b.Nominator;
    var denominatorSum = (dynamic)a.Denominator + b.Denominator;

    return new Racional<T>(nominatorSum, denominatorSum);
}

如果类型没有合适的加法运算符,运算符将抛出。


方法 #2:另一种(更有效的)方法是使用表达式树。

首先,创建并缓存一个可以通过编译适当的表达式来执行加法的委托(delegate):

private readonly static Func<T, T, T> Adder;

static Racional()
{
    var firstOperand = Expression.Parameter(typeof(T), "x");
    var secondOperand = Expression.Parameter(typeof(T), "y");
    var body = Expression.Add(firstOperand, secondOperand);
     Adder = Expression.Lambda<Func<T, T, T>>
                (body, firstOperand, secondOperand).Compile();    
} 

(如果类型没有合适的加法运算符,静态构造函数将抛出异常。)

然后在操作符中使用它:

public static Racional<T> operator *(Racional<T> a, Racional<T> b)
{
    var nominatorSum = Adder(a.Nominator, b.Nominator);
    var denominatorSum = Adder(a.Denominator, b.Denominator);
    return new Racional<T>(nominatorSum, denominatorSum);
}

关于c# - 帮助类里面的数学操作数 (c#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5662808/

相关文章:

找不到php命名空间类 - Twig Composer

C#:获取列表中出现次数最多的元素?

c# - 将标记的枚举解析为列表的最有效方法

java - 了解 Java 中未初始化的对象

类中的 Javascript 递归

linux - 在两个日期变量之间插入文本

c++ - 处理无效操作数错误

c# - 如何验证内部属性是否设置了正确的值?

c# - 如何将参数传递给C#中的线程?

c++ - 映射运算符 [] 操作数