如何使用自定义类型重载 System.Math 方法

3

我目前正在开发一些自定义类型的 Unit,我希望其他用户可以使用数学运算(sin、cos、ln等)。

我想要做的是重载 System.Math 中的数学函数,使其接受 Unit 类型作为参数,这样用户在编写代码时就不必使用两个不同的静态方法 (Math.Sin()Unit.Sin()) 来处理浮点数和 Unit 的计算。我希望对于想使用我的类的人来说,这将会很简单。

如何重载 System.Math 或者有没有其他方法可以实现我的目标呢?


1
你的问题不够清晰。你的 Unit.Sin() 方法是什么样子的?为什么它与 Math.Sin() 方法相似到你觉得在使用它的代码中应该完全一致?如果你的 Unit 类型委托给了 Math 方法本身,你可以使用隐式转换。如果 Unit 类型代码与 Math 代码显著不同,即使可能(实际上不可能)重载 Math 方法也是一个非常糟糕的想法。请澄清问题,包括提供一个 [mcve],以显示你想要做什么。 - Peter Duniho
2个回答

3

欢迎来到Stack Overflow,感谢你的提问。

跟大部分".Net"的东西一样,有多种实现方式。我会使用用户自定义转换运算符

通过使用转换运算符,你的Unit类型可以被转换为其他数据类型。

例如,如果你想使用Unit执行Math.Sin函数,你可以创建一个显式或隐式转换运算符。

public struct Unit
{
    private readonly double value;

    public Unit(double value)
    {
        this.value = value;
    }

    public static implicit operator double(Unit d) => d.value;
    public static explicit operator Unit(double b) => new Unit(b);
}

结果是,Math.Sin(double)现在可以接受一个单位参数。

var unit = new Unit(1d);
var sin = Math.Sin(unit);
Console.WriteLine(sin.ToString(CultureInfo.InvariantCulture));

如果这篇文章不能解答您的疑问,请更详细地告诉我们有关“Unit”类型的信息。随意将您现有的源代码粘贴到原始问题中。

1
这是正确的方法。设计你的类型(Unit)以表现为原始类型,并允许与现有的数值类型之间进行隐式转换。 - JAlex

0
Gabrik 是正确的,你不能只是重载 System.Math。另一个解决方案是完全包装 System.Math 与你自己的类。由于我假设将 double 和 Unit 结合的主要问题是需要先进行某种形式的转换,因此你可以创建一些方法的重载,这些方法将以 Unit 作为参数,并且在任何有效的组合中都可以使用。
这可能看起来比仅重载特定方法更费力,但大部分耗时的工作与如果可能的话重载方法是相同的。其余的方法,你不会重载,只需调用 System.Math 上的基础方法即可。你可以通过任何可用于快速代码生成的技术生成所有该代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接