C#数字基类

时间:2009-09-03 18:10:47

标签: c# polymorphism numbers

我想写一个可以接受任何数字的C#方法。类似的东西:

public static T Sum(T a, T b) where T : number {  // (not real code)
    return a + b;
}

但我没有在C#中看到一个“数字”基类,就像我用过的大多数其他语言一样。数值类型是IComparable,IFormattable,IConvertible,IComparable和IEquatable,但似乎没有任何算术功能。它们都是结构,除了物体外没有明显的共同超类。 (请原谅我,如果我搞砸了这里的意思,因为我不太熟悉C#结构,以及它们的所有方式或类似的方式。)

我是否遗漏了某些内容,或者是否无法在C#中编写一个执行“a + b”的方法而没有在“+”的上下文中明确指出a和b是什么?

6 个答案:

答案 0 :(得分:4)

您将不得不求助于使用重载。有点像Math类正在使用像Math.Max这样的函数,它支持所有数字类型。

CD提出的link也足智多谋。

答案 1 :(得分:3)

有关类似的讨论,请参阅this SO question

此外,如果您愿意为要使用它的每个.Net核心数类型创建单独的类型,您可以执行此操作(需要一些繁琐的工作)。

创建两个结构,名为say,MyInt和MyDecimal,它们充当CTS Int32的外观,以及十进制核心类型(它们包含相应类型的内部字段。)每个结构都应该有一个ctor,它接受一个实例核心CTS类型作为输入参数..

使每个实现一个名为INumeric

的空接口

然后,在您的泛型方法中,根据此接口创建约束。在下方,除了要使用这些方法之外,还必须构造适当的自定义类型的实例而不是Core CTS类型,并将自定义类型传递给方法。

注意:编写自定义结构以正确模拟核心CTS类型的所有行为是繁琐的部分......您必须实现几个内置的CLR接口(IC Comparable等)并重载所有算法,并且布尔运算符...

答案 2 :(得分:2)

不幸的是,不存在这样的类/接口。

答案 3 :(得分:2)

int和其他数值类型是ValueTypes。如前所述,你所能做的只是说where T: struct。好吧,您可以使用反射来检查类型参数是否实现了添加......但我不确定这是不是一个好主意。

答案 4 :(得分:0)

你能做的最好的是where T : struct,它需要一个ValueType;所有数字都是ValueTypes。

不幸的是,所有用户定义的结构都是如此,所以这就是缺点。没有特定的泛型可以接受所有数字类。

我甚至不建议这样做,但你可能考虑对方法中T的类型进行运行时检查,如果T不是int,则抛出,long,短,浮动或双重。不幸的是,这对编程时的程序员没有帮助。

答案 5 :(得分:0)

这是一个非常常见的问题;如果您使用的是.NET 3.5,那么MiscUtil中有很多支持,通过Operator类,它支持内置类型和任何带有运算符的自定义类型(包括“提升”运算符);特别是,这允许与泛型一起使用,例如:

public static T Sum<T>(this IEnumerable<T> source) {
    T sum = Operator<T>.Zero;
    foreach (T value in source) {
        if (value != null) {
            sum = Operator.Add(sum, value);
        }
    }
    return sum;
}

或者另一个例子; Complex<T>