C#数值类型的“基类”是什么?

时间:2009-05-06 09:27:51

标签: c# types

假设我想拥有一个可以使用任何类型数字的方法,是否有可以使用的基类(或其他一些概念)?

据我所知,我必须为所有不同的数字类型(Int32,Int16,Byte,UInt32,Double,Float,Decimal等)进行重载。这看起来非常乏味。或者使用类型“对象”并抛出异常,如果它们不可转换或可分配给double - 这非常糟糕,因为它意味着没有编译时间检查。

更新 好的感谢您的评论,你是对的Scarecrow和Marc,实际上宣称它是Double实际上适用于除Decimal以外的所有人。

所以我正在寻找的答案是Double - 它在这里就像一个基类,因为大多数数字类型都可以分配给它。 (我猜Decimal不能分配给Double,因为它可能会变得太大。)

public void TestFormatDollars() {
    int i = 5;
    string str = FormatDollars(i);   // this is OK
    byte b = 5;
    str = FormatDollars(b);     // this is OK
    decimal d = 5;
    str = FormatDollars(d);     // this does not compile - decimal is not assignable to double
}

public static string FormatDollars(double num) {
    return "$" + num;
}

6 个答案:

答案 0 :(得分:22)

答案是:您不需要为所有数字类型提供重载,仅适用于 Double Decimal 。所有其他的(除了一些非常大的异常)将自动转换为这些。

不是基类,但事实上那是红鲱鱼。基类System.ValueType没有多大帮助,因为它包含非数字类型。我正在阅读的语言参考是让我困惑的原因:)

(我只是在寻找将答案归于何处的人,而且它是Scarecrow和Marc Gravell的组合,但由于他们是评论我在这里提出了答案)

答案 1 :(得分:13)

没有一个(或者至少没有一个只是意味着“数字”)。你可以使用:

void Foo<T>(T value) where T : struct {...}

但是这允许任何结构 - 而不仅仅是数字。如果你想算术,generic operators可能会有用。除此之外;超载它是最可行的选择。

答案 2 :(得分:10)

简短的回答是:数字类型是值类型,因此它们派生自System.ValueType。 完整的答案是:你应该阅读article from MSDN。而且我认为你应该阅读C#语言参考:)。值类型不等于数字类型,因为值类型还包括结构和枚举。

答案 3 :(得分:7)

我的所作所为:

 public interface INumeric<T>
 {
     T Zero { get; }
     T One { get; }
     T MaxValue { get; }
     T MinValue { get; }
     T Add(T a, T b);
     // T Substract(....
     // T Mult...
 }  

 public struct Numeric: 
     INumeric<int>, 
     INumeric<float>,
     INumeric<byte>,
     INumeric<decimal>,
     // INumeric<other types>
 {
     int INumeric<int>.Zero => 0;
     int INumeric<int>.One => 1;
     int INumeric<int>.MinValue => int.MinValue;
     int INumeric<int>.MaxValue => int.MaxValue;
     int INumeric<int>.Add(int x, int y) => x + y;

     // other implementations...
 }

现在,您可以在方法中使用它:

bool IsZero<TNum, T>(TNum ops, T number) 
   where TNum : INumeric<T>
{
   return number == ops.Zero;      
}

或扩展方法

 public static bool IsZero<TNum, T>(this TNum ops, T number)
      where TNum : INumeric<T>
 {
      return number == ops.Zero;
 }

并在您的代码中:

 ...
 var n = new Numeric(); // can be an static prop

 Console.WriteLine(IsZero(n, 5)); // false
 Console.WriteLine(IsZero(n, 0f)); // true
 Console.WriteLine(IsZero(n, "0")); // compiler error

或,使用扩展方法:

 Console.WriteLine(n.IsZero(5));  // false
 Console.WriteLine(n.IsZero(0f)); // true
 Console.WriteLine(n.IsZero("0")); // compiler error

答案 4 :(得分:5)

数字类型的基类是ValueType

不幸的是,它仍然无法帮助您:DateTimeboolEnum以及数百种其他类型也来自ValueType。 .NET中没有NumericType基类。

答案 5 :(得分:0)

这里的方法签名是否超载? 如果您希望一组约束方法执行相同的任务,您可以通过将输入转换为double来调用公共方法并调用一个私有方法来获取任何数字。