【问题标题】:Is there a way to overload math function for a custom type?有没有办法为自定义类型重载数学函数?
【发布时间】:2018-10-15 15:30:49
【问题描述】:

我知道您可以为自定义类型执行运算符重载 (+-*/)。有没有办法对自定义数学函数做同样的事情?这将使向量操作更自然(如在 R 中)。示例:

vector = [1, 2, 3, 4, 5]

vector + vector = [2, 4, 6, 8, 10]  # can be achieved with operator overloading
vector * 5 = [5, 10, 15, 20, 25] # can be achieved with operator overloading

pow(vector, 2) = [ 1, 4, 9, 16, 25 ]  # is it possible in C#?

更新
从下面的答案中,我看到“函数重载”是不可能的(可能没有多大意义),最好的处理方法是创建自定义数学函数库(静态类)。
该解决方案很好,尽管有没有办法将“自定义函数”与其他自定义类型重用?假设我有数字(int/float)、复数、向量和矩阵(向量数组)。我希望我的 Pow 函数适用于所有 4 种类型(它应该为对象中的每个数字元素提供动力)。
另外,有没有办法让函数根据输入类型做不同的事情?例如

abs(-1) = 1  # for integer abs just change the sign if negative
abs(4+3i) = sqrt(4^2+3^2) = 5 # smth different for complex number

【问题讨论】:

  • 您只需编写自己的pow 方法。这不能满足你的需求吗?
  • 那个,或者你可以重载^ 操作符,但这可能会带来一些混乱。
  • 不,这只是伪代码。假设我有使用整数/浮点数的标准数学库,想知道是否有办法将它与向量类型重用。
  • pow 只是一个例子。我想将它与 sin、cos、sqrt 等其他函数一起使用

标签: c# .net operator-overloading


【解决方案1】:

您可以通过利用 C# 6 中添加的using static 功能来实现类似的目的。这使您可以使类中的静态方法可用,而无需指定类型名称。 (.NET Math 类经常被引用为此功能的 example。)

假设一个实现IEnumerable<double>Vector 类,您可以创建一个包含您的静态Pow 函数的类:

namespace Vectors
{
    public static class VectorMath
    {
        public static Vector Pow(Vector v, int exponent)
        {
            return new Vector(v.Select(n => Math.Pow(n, exponent)));
        }
    }
}

然后,在您要使用此类的任何代码文件中,包含该语句

using static Vectors.VectorMath;

这将允许您调用Pow 方法而无需指定它是VectorMath 类的成员:

class Program
{
    static void Main(string[] args)
    {
        Vector v = new Vector { 1, 2, 3 };
        Vector squares = Pow(v, 2);

        // Squares now contains [1, 4, 9]
    }
}

【讨论】:

  • 听起来是一个很好的解决方案,至少方法与向量类分离(我会说这是我的主要要求)。理想情况下,我想让所有数学函数(或自定义函数集)一次性使用矢量类型(而不是为每个函数创建包装器)。这可能是不可能的,只是想确保我没有错过一些魔术
  • @MikeTwc 不幸的是,这是不可能的,数学超出了 C# 中泛型的能力。您可以在 LINQ 中看到这一点,例如Enumerable.Sum 具有所有数字类型及其可为空的变体的重载。您也许可以提取一些通用语义,但如果您最终考虑一下,Pow 等函数具有特定于类型的实现(通常取决于平台的指令集),因此提供通用软件实现没有多大意义在框架级别。
【解决方案2】:

您可以为 Array 类创建扩展方法 pow()

 public static class VecorExtension
{
        public static void pow(this Array vector, int i)
        {
            ...
        }
}

用法:

[1,2,3].pow(2);

Extension methods

【讨论】:

  • 恐怕这会将扩展方法添加到所有 Array 类型中,这可能非常违反直觉,更不用说实现复杂性了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多