如果我有一个计算两个整数的最大公约数的方法:
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
将它附加到System.Math类的最佳方法是什么?
以下是我提出的三种方式:
public static int GCD(this int a, int b)
{
return b == 0 ? a : b.GCD(a % b);
}
// Lame...
var gcd = a.GCD(b);
和
public static class RationalMath
{
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
// Lame...
var gcd = RationalMath.GCD(a, b);
和
public static int GCD(this Type math, int a, int b)
{
return b == 0 ? a : typeof(Math).GCD(b, a % b);
}
// Neat?
var gcd = typeof(Math).GCD(a, b);
所需语法为Math.GCD
,因为这是所有数学函数的标准。
有什么建议吗?我该怎么做才能获得所需的语法?
答案 0 :(得分:11)
你做不到。扩展方法只是用于调用静态函数和传递特定类型实例的语法糖。鉴于此,它们仅在实例上运行,因为它们必须通过传递要附加的类型的this
参数来定义。
答案 1 :(得分:6)
我更喜欢RationalMath
的那个。你真的不需要这里的扩展方法,因为他们的目的是模仿你无法修改的对象的实例方法。但是这里应该使用普通的静态方法。
答案 2 :(得分:4)
鉴于您无法扩展静态Math
类,我会选择样本#2。它遵循Math使用的模式,不会使int
方法空间混乱,并且调用简单而干净。 #3非常可怕:)
答案 3 :(得分:3)
就个人而言,我不会按照你想要的方式去做。 System.Math
只是一个包含一些数学函数的静态类。 。 。没有理由它必须包含你想要使用的每个数学函数。
但是,如果确实想要这个,我想你可以编写自己的静态Math类,它是System.Math
的一种包装器。 。 。基本上只是通过将它传递给实际的System.Math
类来实现System.Math
中的每个函数。像这样:
public static class Math
{
public static int GCD(int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
// Implement the System.Math methods
public static double Pow(double x, double y)
{
return System.Math.Pow(x, y);
}
// etc.
}
这似乎是一个真正的痛苦,虽然没有太大的好处。 (一种反 -syntactic糖。)但它可以让你从同一个班级拨打Math.GCD(a,b)
,比如Math.Pow(x,y)
,这听起来像是你想要的
答案 4 :(得分:0)
好的,我想到的另一种方式:
namespace My
{
public static class Math
{
}
}
namespace MainApp
{
...
var gcd = My.Math.GCD(a, b);
...
}