Обнуляемые типы: лучший способ проверить наличие нуля или нуля в 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));
}
}