Обнуляемые типы: лучший способ проверить наличие нуля или нуля в c #

Я работаю над проектом, где я нахожу, что проверяю следующее во многих и многих местах:

if(item.Rate == 0 || item.Rate == null) { }

больше как любопытство, чем что-либо, что лучший способ проверить оба случая?

Я добавил вспомогательный метод, который:

public static bool nz(object obj)
{
    var parsedInt = 0;
    var parsed = int.TryParse(obj.ToString(), out parsedInt);
    return IsNull(obj) || (parsed && parsedInt == 0);
}

Есть ли лучший способ?

Ответ 1

Мне нравится if ((item.Rate ?? 0) == 0) { }

Обновление 1:

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

public static bool IsNullOrValue(this double? value, double valueToCheck)
{
    return (value??valueToCheck) == valueToCheck;
}

И используйте его следующим образом:

if(item.IsNullOrValue(0)){}//но вы не получаете от него много чего.

Ответ 2

Использование дженериков:

static bool IsNullOrDefault<T>(T value)
{
    return object.Equals(value, default(T));
}

//...
double d = 0;
IsNullOrDefault(d); // true
MyClass c = null;
IsNullOrDefault(c); // true

Если T, ссылочный тип value будет сравниваться с null (default(T)), в противном случае, если T является value type, допустим, double, default(T) равен 0d, для bool - false, для char - '\0' и так далее...

Ответ 3

Хотя мне очень нравится принятый ответ, я думаю, что для полноты этой опции следует упомянуть:

if (item.Rate.GetValueOrDefault() == 0) { }

Это решение


¹ Это не должно влиять на ваше решение, поскольку эти виды микро-оптимизации вряд ли будут иметь какое-либо значение.

Ответ 4

Это действительно просто расширение принятого ответа Фредди Риоса только с использованием Generics.

public static bool IsNullOrDefault<T>(this Nullable<T> value) where T : struct
{
    return default(T).Equals( value.GetValueOrDefault() );
}

public static bool IsValue<T>(this Nullable<T> value, T valueToCheck) where T : struct
{
    return valueToCheck.Equals((value ?? valueToCheck));
}

ПРИМЕЧАНИЕ нам не нужно проверять значение по умолчанию (T) для null, так как мы имеем дело с любыми типами значений или структурами! Это также означает, что мы можем с уверенностью предположить, что значение TToCheck не будет равно нулю; Помните, что T? является сокращением Nullable <T> поэтому добавив расширение к Nullable <T> мы получаем метод в int?, double?, bool? и др.

<сильные > Примеры:

double? x = null;
x.IsNullOrDefault(); //true

int? y = 3;
y.IsNullOrDefault(); //false

bool? z = false;
z.IsNullOrDefault(); //true

Ответ 5

Я согласен с использованием оператор.

Если вы имеете дело со строками, используйте (String.IsNullOrEmpty(myStr))

Ответ 6

Образец кода образца не будет выполнен. Если obj равно null, то obj.ToString() приведет к исключению нулевой ссылки. Я бы сократил процесс и проверил нулевой объект в начале вашей вспомогательной функции. Что касается вашего фактического вопроса, какой тип вы проверяете на нуль или ноль? В String есть отличная функция IsNullOrEmpty, мне кажется, что это было бы большим использованием методов расширения для реализации метода IsNullOrZero для int? тип.

Изменить: помните, что?? это просто сахара-компилятор для типа INullable, поэтому вы, вероятно, можете взять INullable как parm, а затем сравнить его с null (parm == null), а если не null, сравните с нолем.

Ответ 7

есть ли лучший способ?

Хорошо, если вы действительно ищете лучший способ, вы можете добавить еще один слой абстракции поверх Rate. Ну вот что-то я только что придумал с помощью Nullable Design Pattern.

using System;
using System.Collections.Generic;

namespace NullObjectPatternTest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var items = new List
                            {
                                new Item(RateFactory.Create(20)),
                                new Item(RateFactory.Create(null))
                            };

            PrintPricesForItems(items);
        }

        private static void PrintPricesForItems(IEnumerable items)
        {
            foreach (var item in items)
                Console.WriteLine("Item Price: {0:C}", item.GetPrice());
        }
    }

    public abstract class ItemBase
    {
        public abstract Rate Rate { get; }
        public int GetPrice()
        {
            // There is NO need to check if Rate == 0 or Rate == null
            return 1 * Rate.Value;
        }
    }

    public class Item : ItemBase
    {
        private readonly Rate _Rate;
        public override Rate Rate { get { return _Rate; } }
        public Item(Rate rate) { _Rate = rate; }
    }

    public sealed class RateFactory
    {
        public static Rate Create(int? rateValue)
        {
            if (!rateValue || rateValue == 0) 
                return new NullRate();
            return new Rate(rateValue);
        }
    }

    public class Rate
    {
        public int Value { get; set; }
        public virtual bool HasValue { get { return (Value > 0); } }
        public Rate(int value) { Value = value; }
    }

    public class NullRate : Rate
    {
        public override bool HasValue { get { return false; } }
        public NullRate() : base(0) { }
    }
}

Ответ 8

public static bool nz(object obj)
{
    return obj == null || obj.Equals(Activator.CreateInstance(obj.GetType()));
}

Ответ 9

class Item{  
 bool IsNullOrZero{ get{return ((this.Rate ?? 0) == 0);}}
}

Ответ 10

Не забывайте, что для строк вы всегда можете использовать:

String.IsNullOrEmpty(str)

Вместо:

str==null || str==""

Ответ 11

В шаге от Джошуа Шеннона хороший ответ. Теперь с предотвращением бокса/распаковки:

public static class NullableEx
{
    public static bool IsNullOrDefault<T>(this T? value)
        where T : struct
    {
        return EqualityComparer<T>.Default.Equals(value.GetValueOrDefault(), default(T));
    }
}