有没有办法编写适用于多种类型的扩展方法?

问题描述 投票:0回答:2

我正在尝试编写一个扩展方法,将函数

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# .net types extension-methods
2个回答
6
投票

不,这在 C# 中是不可能的。您必须为每种类型创建一个扩展方法。最接近的是有一个在接口上操作的扩展方法,但在这种情况下,没有 INumeric 接口或由各种数字类型实现的任何类似接口。


0
投票

是的,使用泛型和约束可以实现这一点。

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 作为约束。此扩展方法适用于以下类型:

  1. 系统.字节
  2. 系统.Char
  3. 系统.Int16
  4. 系统.Int32
  5. 系统.Int64
  6. 系统.SByte
  7. 系统.UInt16
  8. 系统.UInt32
  9. 系统.UInt64

我希望这对有一天偶然发现这个问题的人有所帮助。快乐编码:)

© www.soinside.com 2019 - 2024. All rights reserved.