type number long implicita data convert conversion c# types

number - ¿Cuál es la "clase base" para los tipos de valores numéricos C#?



type integer c# (6)

Digamos que quiero tener un método que tenga cualquier tipo de número, ¿existe una clase base (o algún otro concepto) que pueda usar?

Hasta donde sé, tengo que hacer sobrecargas para todos los diferentes tipos numéricos (Int32, Int16, Byte, UInt32, Double, Float, Decimal, etc.). Esto parece terriblemente tedioso. O eso, o usa el tipo "objeto" y lanza excepciones si no son convertibles o asignables a un doble, lo cual es bastante malo, ya que significa que no hay tiempo de compilación.

ACTUALIZACIÓN: OK, gracias por los comentarios, tienes razón Espantapájaros y Marc, de hecho declararlo como Doble realmente funciona para todos excepto para Decimal.

Entonces, la respuesta que estaba buscando es Doble: aquí actúa como una clase base, ya que la mayoría de los tipos numéricos son asignables. (Supongo que Decimal no es asignable a Double, ya que podría ser demasiado grande).

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; }


¿Los nombres de métodos sobrecargados están descartados aquí? Si desea que un grupo restringido de métodos realice la misma tarea, puede descargar el método público y llamar a un método privado que toma cualquier número al convertir la entrada en un doble.


La clase base de los tipos numéricos es ValueType .

Lamentablemente, eso no lo ayudará: DateTime , bool , Enum y cientos de otros tipos también se derivan de ValueType . No hay clase base NumericType en .NET.


La respuesta corta es: los tipos numéricos son tipos de valores, por lo tanto, derivan de System.ValueType. La respuesta completa es: debe leer este artículo de MSDN . Además, creo que deberías leer la referencia del lenguaje C # :). El tipo de valor no es igual al tipo numérico, porque los tipos de valores también incluyen estructuras y enumeraciones.


La respuesta es: no necesita proporcionar sobrecargas para TODOS los tipos numéricos, solo para Doble y Decimal . Todos los demás (excepto quizás algunos muy inusualmente grandes) se convertirán automáticamente a estos.

No es una clase base, pero de hecho esa fue la arenga roja. La clase base System.ValueType no ayuda mucho ya que incluye tipos que no son numéricos. La referencia de idioma que estaba leyendo fue lo que me confundió en primer lugar :)

(Estaba buscando a quién atribuirle la respuesta y era una combinación de Scarecrow y Marc Gravell, pero dado que eran comentarios, he puesto la respuesta aquí)


Lamentablemente, no hay una clase base para ningún tipo de número. Pero puede crear una clase con un molde implícito de cada tipo de número y para cada tipo de número, como este:

#region Imports using System.Diagnostics; #endregion namespace System { public class Number { #region Variables private decimal number = 0; #endregion #region Override Methods [DebuggerHidden] public override int GetHashCode() { return this.number.GetHashCode(); } [DebuggerHidden] public override bool Equals(object obj) { if (!(obj is Number)) return false; return this.number == ((Number)obj).number; } [DebuggerHidden] public override string ToString() { return this.number.ToString(); } #endregion #region Operators [DebuggerHidden] public static Number operator +(Number a, Number b) { return a.number + b.number; } [DebuggerHidden] public static Number operator -(Number a, Number b) { return a.number - b.number; } [DebuggerHidden] public static Number operator *(Number a, Number b) { return a.number * b.number; } [DebuggerHidden] public static Number operator /(Number a, Number b) { return a.number / b.number; } [DebuggerHidden] public static Number operator %(Number a, Number b) { return a.number % b.number; } [DebuggerHidden] public static Number operator &(Number a, Number b) { return (int)a & (int)b; } [DebuggerHidden] public static Number operator |(Number a, Number b) { return (int)a | (int)b; } [DebuggerHidden] public static Number operator ^(Number a, Number b) { return (int)a ^ (int)b; } [DebuggerHidden] public static Number operator <<(Number a, int b) { return (int)a << b; } [DebuggerHidden] public static Number operator >>(Number a, int b) { return (int)a >> b; } [DebuggerHidden] public static bool operator ==(Number a, Number b) { return a.Equals(b); } [DebuggerHidden] public static bool operator !=(Number a, Number b) { return !a.Equals(b); } [DebuggerHidden] public static bool operator <(Number a, Number b) { return a.number < b.number; } [DebuggerHidden] public static bool operator <=(Number a, Number b) { return a.number <= b.number; } [DebuggerHidden] public static bool operator >(Number a, Number b) { return a.number > b.number; } [DebuggerHidden] public static bool operator >=(Number a, Number b) { return a.number >= b.number; } [DebuggerHidden] public static implicit operator decimal(Number num) { return num.number; } [DebuggerHidden] public static implicit operator double(Number num) { return (double)num.number; } [DebuggerHidden] public static implicit operator float(Number num) { return (float)num.number; } [DebuggerHidden] public static implicit operator int(Number num) { return (int)num.number; } [DebuggerHidden] public static implicit operator short(Number num) { return (short)num.number; } [DebuggerHidden] public static implicit operator byte(Number num) { return (byte)num.number; } [DebuggerHidden] public static implicit operator string(Number num) { return num.number.ToString(); } [DebuggerHidden] public static implicit operator Number(decimal num) { Number i = new Number(); i.number = num; return i; } [DebuggerHidden] public static implicit operator Number(double num) { return (decimal)num; } [DebuggerHidden] public static implicit operator Number(float num) { return (decimal)num; } [DebuggerHidden] public static implicit operator Number(int num) { return (decimal)num; } [DebuggerHidden] public static implicit operator Number(short num) { return (decimal)num; } [DebuggerHidden] public static implicit operator Number(byte num) { return (decimal)num; } #endregion } }

Y aquí está cómo usar la clase: ¡escribe simplemente todos los números!

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 is OK too!!! } public static string FormatDollars(Number num) { return "$" + num; }


No hay uno (o al menos, ninguno que solo signifique "números"). Podrías usar:

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

Pero eso permite cualquier estructura, no solo números. Si desea hacer aritmética, los operadores genéricos pueden ser de utilidad. Aparte de eso; lo sobrecarga la opción más viable.