假设我想拥有一个可以使用任何类型数字的方法,是否有可以使用的基类(或其他一些概念)?
据我所知,我必须为所有不同的数字类型(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;
}
答案 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
。
不幸的是,它仍然无法帮助您:DateTime
,bool
,Enum
以及数百种其他类型也来自ValueType
。 .NET中没有NumericType
基类。
答案 5 :(得分:0)
这里的方法签名是否超载? 如果您希望一组约束方法执行相同的任务,您可以通过将输入转换为double来调用公共方法并调用一个私有方法来获取任何数字。