Nullable-Typ: bester Weg für null oder null in c # überprüfen
Frage
Ich arbeite an einem Projekt, wo ich Ich überprüfe die folgenden finden in vielen, vielen Orten:
if(item.Rate == 0 || item.Rate == null) { }
mehr als curiousity als alles, was der beste Weg für beide Fälle zu überprüfen ist?
Ich habe eine Hilfsmethode gegeben, das ist:
public static bool nz(object obj)
{
var parsedInt = 0;
var parsed = int.TryParse(obj.ToString(), out parsedInt);
return IsNull(obj) || (parsed && parsedInt == 0);
}
Gibt es einen besseren Weg?
Lösung
Ich mag if ((item.Rate ?? 0) == 0) { }
Update 1:
Sie können auch eine Erweiterungsmethode wie definieren
public static bool IsNullOrValue(this double? value, double valueToCheck)
{
return (value??valueToCheck) == valueToCheck;
}
Und es wie folgt verwendet werden:
if(item.IsNullOrValue(0)){}
// aber bekommt man nicht viel von ihr
Andere Tipps
Mit Generika:
static bool IsNullOrDefault<T>(T value)
{
return object.Equals(value, default(T));
}
//...
double d = 0;
IsNullOrDefault(d); // true
MyClass c = null;
IsNullOrDefault(c); // true
Wenn T
es ist ein Referenztyp , wird value
verglichen werden mit null
(default(T)
), sonst, wenn T
ein value type
ist, sagen wir mal doppelt, ist default(t)
0T, für Bool false
ist, für char '\0'
ist und so weiter ...
Obwohl ich ganz wie die akzeptierte Antwort, glaube ich, dass für Vollständigkeit, sollte diese Option auch erwähnt werden:
if (item.Rate.GetValueOrDefault() == 0) { }
Diese Lösung
- keine zusätzliche Methode erfordert,
- ist schneller als alle anderen Optionen, da GetValueOrDefault ist ein einzelnes Feld Lesevorgang ¹ und
- einfacher als
((item.Rate ?? 0) == 0)
liest (dies könnte eine Frage des Geschmacks sein, obwohl).
¹ Dies sollte Ihre Entscheidung nicht beeinflussen, obwohl, da diese Art von Mikro-Optimierung ist es unwahrscheinlich, einen Unterschied machen.
Das ist wirklich nur eine Erweiterung von Freddy Rios' akzeptierten Antwort nur Generics verwendet wird.
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));
}
Hinweis die wir nicht brauchen default (T) für null zu überprüfen, da wir entweder mit Werttypen oder structs tun haben! Das bedeutet auch, können wir sicher T valueToCheck nicht null annehmen wird; Denken Sie daran, dass hier T? ist eine Abkürzung Nullable
Beispiele:
double? x = null;
x.IsNullOrDefault(); //true
int? y = 3;
y.IsNullOrDefault(); //false
bool? z = false;
z.IsNullOrDefault(); //true
Ich bin damit einverstanden die mit der Verwendung von ?? Operator.
Wenn Sie mit Strings zu tun hat verwenden, wenn (String.IsNullOrEmpty (myStr))
Gibt es einen besseren Weg?
Nun, wenn Sie wirklich nach einem besseren Weg suchen, können Sie wahrscheinlich eine weitere Ebene der Abstraktion auf der Rate hinzuzufügen. Nun, hier ist etwas, das ich kam gerade mit der Verwendung von Nullable Design Mustern auf.
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) { } } }
Sie werden Codebeispiel fehlschlagen. Wenn obj null ist, dann wird die obj.ToString () in einer Null-Referenz Ausnahme führen. Ich habe kurz den Prozess schneiden und prüfen, ob einen Null-obj zu Beginn Ihrer Helferfunktion. In Bezug auf Ihre eigentliche Frage, was ist der Typ, den Sie für null oder null sind prüfen? Auf String gibt es eine große IsNullOrEmpty Funktion, scheint mir, das wäre ein großer Einsatz von Erweiterungsmethoden sein, eine IsNullOrZero Methode auf dem int zu implementieren? Art.
Edit: Denken Sie daran, das '?' Zucker ist nur Compiler für den INullable Typen, so dass Sie wahrscheinlich eine INullable als Parm nehmen könnten und dann jsut vergleichen Null zu bringen (Parm == null) und null zu vergleichen, wenn nicht.
public static bool nz(object obj)
{
return obj == null || obj.Equals(Activator.CreateInstance(obj.GetType()));
}
class Item{
bool IsNullOrZero{ get{return ((this.Rate ?? 0) == 0);}}
}
Vergessen Sie nicht, für Streicher, können Sie immer wie folgt:
String.IsNullOrEmpty(str)
Statt:
str==null || str==""
Ein weiterer Schritt von Joshua Shannon ist schön Antwort . Jetzt mit der Verhinderung Boxen / 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));
}
}