I\'m working on a project where i find i\'m checking for the following in many, many places:
if(item.Rate == 0 || item.Rate == null) { }
mo
public static bool nz(object obj)
{
return obj == null || obj.Equals(Activator.CreateInstance(obj.GetType()));
}
Don't forget, for strings, you can always use:
String.IsNullOrEmpty(str)
Instead of:
str==null || str==""
Although I quite like the accepted answer, I think that, for completeness, this option should be mentioned as well:
if (item.Rate.GetValueOrDefault() == 0) { }
This solution
((item.Rate ?? 0) == 0)
(this might be a matter of taste, though).¹ This should not influence your decision, though, since these kinds of micro-optimization are unlikely to make any difference.
is there a better way?
Well, if you are really looking for a better way, you can probably add another layer of abstraction on top of Rate. Well here is something I just came up with using 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) { } } }
One step further from Joshua Shannon's nice answer. Now with preventing boxing/unboxing:
public static class NullableEx
{
public static bool IsNullOrDefault<T>(this T? value)
where T : struct
{
return EqualityComparer<T>.Default.Equals(value.GetValueOrDefault(), default(T));
}
}
This is really just an expansion of Freddy Rios' accepted answer only using 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));
}
NOTE we don't need to check default(T) for null since we are dealing with either value types or structs! This also means we can safely assume T valueToCheck will not be null; Remember here that T? is shorthand Nullable<T> so by adding the extension to Nullable<T> we get the method in int?, double?, bool? etc.
Examples:
double? x = null;
x.IsNullOrDefault(); //true
int? y = 3;
y.IsNullOrDefault(); //false
bool? z = false;
z.IsNullOrDefault(); //true