我正在尝试编写一个扩展方法,将函数
HasFactor
添加到 C# 中的类 int
中。 这效果非常好,就像这样:
static class ExtendInt
{
public static bool HasFactor(this int source, int factor)
{
return (source % factor == 0);
}
}
class Program
{
static void Main()
{
int i = 50;
int f = 2;
bool b = i.HasFactor(f);
Console.WriteLine("Is {0} a factor of {1}? {2}",f,i,b);
Console.ReadLine();
}
}
这非常有效,因为上面
i
方法中的变量 Main()
被声明为 int
。 但是,如果 i
被声明为 Int16
或 Int64
,则扩展方法不会显示,除非将其显式转换为 int
或 Int32
。
我现在想对
HasFactor
和Int16
应用相同的Int64
方法。 但是,我不想为每种类型的 int
编写单独的扩展方法。 我可以为Int64
编写一个方法,然后将所有内容显式转换为Int64
或long
,以便扩展方法出现。
理想情况下,我希望将相同的扩展方法应用于所有三种类型,而不必复制和粘贴大量代码。
这在 C# 中可能吗?如果不可能,是否有针对此类情况的推荐最佳实践?
不,这在 C# 中是不可能的。您必须为每种类型创建一个扩展方法。最接近的是有一个在接口上操作的扩展方法,但在这种情况下,没有 INumeric 接口或由各种数字类型实现的任何类似接口。
是的,使用泛型和约束可以实现这一点。
static class ExtendInt
{
public static bool HasFactor<T>(this T source, int factor) where T : IBinaryInteger<T>
{
return (Convert.ToInt64(source) % factor == 0);
}
}
一些使用示例:
UInt64 u = 184467440737095568;
if (u.HasFactor(2)) // true
short s = 9;
if (s.HasFactor(3)) // true
double d = 3.36;
if (d.HasFactor(1)) // does not compile
dynamic x = 9.3;
if (x.HasFactor(8)) // throws a runtime error
泛型允许我们编写适用于多种类型的单一方法。就您而言,我们需要将可以操作的类型限制为整数。为此,我们可以使用 IBinaryInteger 作为约束。此扩展方法适用于以下类型:
我希望这对有一天偶然发现这个问题的人有所帮助。快乐编码:)