Что такое "базовый класс" для типов числовых значений С#?
Скажите, что я хочу иметь метод, который принимает какой-либо номер, есть ли базовый класс (или какая-то другая концепция), которую я могу использовать?
Насколько я знаю, мне приходится делать перегрузки для всех разных числовых типов (Int32, Int16, Byte, UInt32, Double, Float, Decimal и т.д.). Это кажется ужасно утомительным. Либо это, либо используйте тип "объект" и исключайте исключения, если они не могут быть конвертируемыми или присваиваемыми двойнику, что довольно плохо, поскольку это означает, что проверка времени компиляции не выполняется.
UPDATE:
Хорошо спасибо за комментарии, вы правы, 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;
}
Ответы
Ответ 1
Ответ: вам не нужно предоставлять перегрузки для ВСЕХ числовых типов, только для Двойной и Десятичный. Все остальные (за исключением, может быть, очень необычно крупных) будут автоматически преобразованы в них.
Не базовый класс, а на самом деле это была красная селедка. Базовый класс System.ValueType не очень помогает, так как включает типы, которые не являются числами. Язык, на котором я читал, был тем, что меня путало в первую очередь:)
(Я просто искал, кому ответить на этот вопрос, и это комбинация Пугало и Марка Гравелла, но поскольку они были комментариями, я поставил здесь ответ)
Ответ 2
Нет ни одного (или, по крайней мере, не одного, что просто означает "числа" ). Вы можете использовать:
void Foo<T>(T value) where T : struct {...}
Но это допускает любую структуру, а не только числа. Если вы хотите сделать арифметику, общие операторы могут быть полезны. Кроме этого; перегружает его наиболее жизнеспособным вариантом.
Ответ 3
Короткий ответ: числовые типы являются типами значений, поэтому они происходят из System.ValueType.
Полный ответ: вы должны прочитать статью из MSDN. Кроме того, я думаю, что вы должны прочитать ссылку на С# язык:). Тип значения не равен числовому типу, так как типы значений включают также структуры и перечисления.
Ответ 4
Базовый класс числовых типов ValueType
.
К сожалению, вам все равно не помогут: DateTime
, bool
, Enum
и сотни других типов также выводятся из ValueType
. Нет базового класса NumericType
в .NET.
Ответ 5
Перегружены ли методы метода здесь?
Если вы хотите, чтобы ограниченная группа методов выполняла одну и ту же задачу, вы могли бы загрузить публичный метод и вызвать частный метод, который принимает любое число с помощью ввода двоичного ввода.
Ответ 6
К сожалению, для любого типа номера нет базового класса. Но вы можете создать класс с неявным отображением из каждого типа номера и каждого типа номера, например:
#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
}
}
А вот как использовать класс: пишите просто все числа!
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;
}