Как я могу сравнить любой числовой тип с нулем в C # - PullRequest
14 голосов
/ 10 марта 2010

Я хотел бы создать функцию, которая проверяет, имеет ли числовое значение, переданное в качестве аргумента, значение больше нуля. Примерно так:

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? Если произойдет сбой, я верну false. Есть ли лучший (читай короче, более читаемый) способ сделать это?

Edit: Некоторые спрашивают, знаю ли я, что тип будет числовым, почему объект и т. Д. Надеюсь, это прояснит ситуацию.

Эта функция будет частью преобразователя Silverlight, который реализует интерфейс IValueConverter с сигнатурой преобразования

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

Во-первых, я хотел, чтобы конвертер работал только с целыми числами, но мое воображение начало сходить с ума и думать, что если у меня есть числа с плавающей точкой и другие числовые типы. Я хотел сделать конвертер максимально гибким. Сначала я думал, что вся эта дополнительная информация помешает тому, что я хотел сделать, поэтому я не включил ее в свой вопрос.

Ответы [ 7 ]

16 голосов
/ 10 марта 2010

Мои предпочтения будут:

public bool IsGreaterThanZero(object value)
{
    if(value is IConvertible)
    {
        return Convert.ToDouble(value) > 0.0;
    }

    return false;
}

Это будет безопасно обрабатывать все IConvertible типы (включая все типы с плавающей запятой и целые числа в структуре, но также любые пользовательские типы).

14 голосов
/ 10 марта 2010

Знает ли абонент тип? Если да, то как насчет:

public static bool GreaterThanZero<T>(T value) where T : struct, IComparable<T>
{
    return value.CompareTo(default(T)) > 0;
}

Никаких преобразований не требуется, и они должны работать для любых встроенных числовых типов - и для любых разумных типов значений, которые вы придумали сами. (Например, это было бы хорошо с Duration структурой Noda Time.)

Обратите внимание, что вызывающему не обязательно знать тип напрямую - он может знать его только как другой параметр типа с теми же ограничениями. По общему признанию это может не подходить для вашей ситуации, но я думал, что упомяну это в любом случае. Если ничто не знает тип во время компиляции (и вы не хотите, чтобы динамическая типизация выполняла эту работу за вас в C # 4!), Тогда вызов Convert.ToDouble, вероятно, ваш лучший выбор - просто знайте, что это может иметь проблемы System.Numerics.BigInteger из .NET 4.0.

4 голосов
/ 11 марта 2010

А? Какие числовые типы вас интересуют?

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);
3 голосов
/ 10 марта 2010

Вы можете избежать упаковки и распаковки, используя дженерики:

Вот определение функции

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));
2 голосов
/ 10 марта 2010

Попробуйте:

double tempValue;
if(double.TryParse(value.ToString(), out tempValue)
{
  return (tempValue > 0)
}
else 
{
  return false;
}
1 голос
/ 11 марта 2010

Это самый простой и быстрый способ сравнить любой числовой тип с нулем следующим образом:

public bool IsGreaterThanZero(object value) 
{ 
    if (value != null && value.GetType().IsValueType)
        return System.Convert.ToDouble(value) > 0;
    return false; 
}
1 голос
/ 10 марта 2010

Почему бы не просто Convert.ToDouble или Convert.ToDecimal, а затем сделать сравнение? Похоже, что он будет обрабатывать большинство типов, которые кто-то может передать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...