Как я могу сравнить любой числовой тип с нулем в С#
Я хотел бы создать функцию, которая проверяет, имеет ли числовое значение, переданное как аргумент, значение больше нуля. Что-то вроде этого:
public bool IsGreaterThanZero(object value)
{
if(value is int)
{
return ((int)value > 0);
}
else if(value is float)
{
// Similar code for float
}
return false;
}
Могу ли я попытаться передать объект, переданный в качестве аргумента функции, в один числовой тип данных, чтобы затем сравнить его с нолем, а не проверять каждый тип в инструкции if? Если сбой броска, я верну ложь. Есть ли лучший (читайте более короткий, более читаемый) способ сделать это?
Edit:
Некоторые спрашивают, знаю ли я, что тип будет числовым, почему объект и т.д. Надеюсь, это упростит ситуацию.
Эта функция будет частью преобразователя Silverlight, который реализует интерфейс IValueConverter
, который имеет подпись преобразования
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
Во-первых, я только хотел, чтобы конвертер работал с ints, но мое воображение начало бегать и думать, что, если у меня есть числа с плавающей запятой и другие числовые типы. Я хотел сделать преобразователь максимально гибким. Первоначально я думал, что вся эта дополнительная информация будет мешать тому, что я хотел сделать, поэтому я не включил ее в свой вопрос.
Ответы
Ответ 1
Мое предпочтение было бы:
public bool IsGreaterThanZero(object value)
{
if(value is IConvertible)
{
return Convert.ToDouble(value) > 0.0;
}
return false;
}
Это будет безопасно обрабатывать все IConvertible (включая все типы с плавающей запятой и целое в структуре, а также любые пользовательские типы).
Ответ 2
Знает ли вызывающий абонент тип? Если да, то как насчет:
public static bool GreaterThanZero<T>(T value) where T : struct, IComparable<T>
{
return value.CompareTo(default(T)) > 0;
}
Нет необходимости в конверсиях и должно работать для любого из встроенных числовых типов - и любых разумных типов значений, которые вы придумываете сами. (Например, это было бы хорошо с Noda Time Duration
struct.)
Обратите внимание, что вызывающий объект не должен знать тип напрямую - он может знать только его как другой параметр типа с теми же ограничениями. По общему признанию, это может быть неприемлемо для вашей ситуации, но я думал, что упомянул об этом. Если ничего не известно о типе во время компиляции (и вы не хотите получать динамическую типизацию для выполнения задания для вас на С# 4!), То вызов Convert.ToDouble
, вероятно, лучший выбор - просто имейте в виду, что у него могут быть проблемы для System.Numerics.BigInteger
из .NET 4.0.
Ответ 3
А? Какие числовые типы вам интересны?
public bool IsGreaterThanZero(double value)
{
return value > 0;
}
Все эти работы...
IsGreaterThanZero((int)2);
IsGreaterThanZero((long)2);
IsGreaterThanZero((double)2);
IsGreaterThanZero((float)2);
IsGreaterThanZero((byte)2);
IsGreaterThanZero((ulong)2);
Ответ 4
Вы можете избежать бокса и распаковки с помощью дженериков:
Здесь определение функции
class GenericComparation {
public static bool IsGreaterThanZero<T>(T value) where T : IComparable<T> {
// Console.WriteLine(value.GetType().Name)
return value.CompareTo(default(T)) > 0;
}
}
Использование:
Console.WriteLine(GenericComparation.IsGreaterThanZero(1));
Console.WriteLine(GenericComparation.IsGreaterThanZero(-1.1));
Console.WriteLine(GenericComparation.IsGreaterThanZero(Decimal.Zero));
Ответ 5
Try:
double tempValue;
if(double.TryParse(value.ToString(), out tempValue)
{
return (tempValue > 0)
}
else
{
return false;
}
Ответ 6
Почему бы просто не конвертировать. ToDouble или Convert.ToDecimal, а затем выполнить сравнение? Похоже, что это будет обрабатывать большинство типов, которые кто-то может пройти.
Ответ 7
Этот самый простой и быстрый способ сравнения любого числового типа. Для нуля:
public bool IsGreaterThanZero(object value)
{
if (value != null && value.GetType().IsValueType)
return System.Convert.ToDouble(value) > 0;
return false;
}