![](/img/trans.png)
[英]Is this a better way to fire/invoke events without a null check in C#?
[英]Nullable types: better way to check for null or zero in 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);
}
有没有更好的办法?
我喜欢if ((item.Rate?? 0) == 0) { }
更新1:
您还可以定义一个扩展方法,例如:
public static bool IsNullOrValue(this double? value, double valueToCheck)
{
return (value??valueToCheck) == valueToCheck;
}
并像这样使用它:
if(item.IsNullOrValue(0)){}
// 但你并没有从中得到太多
使用 generics:
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'
等等...
虽然我非常喜欢接受的答案,但我认为,为了完整起见,也应该提到这个选项:
if (item.Rate.GetValueOrDefault() == 0) { }
这个解决方案
((item.Rate?? 0) == 0)
更容易阅读(不过,这可能是一个口味问题)。¹但这不应该影响您的决定,因为这些类型的微优化不太可能产生任何影响。
这实际上只是 Freddy Rios 接受的答案的扩展,仅使用 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));
}
注意我们不需要检查 null 的默认值(T),因为我们正在处理值类型或结构; 这也意味着我们可以安全地假设 T valueToCheck 不会是 null? 还记得那个T吗? 是 Nullable<T> 的简写,所以通过向 Nullable<T> 添加扩展,我们得到 int 中的方法,? 双倍的,? 布尔。 等等
例子:
double? x = null;
x.IsNullOrDefault(); //true
int? y = 3;
y.IsNullOrDefault(); //false
bool? z = false;
z.IsNullOrDefault(); //true
我同意使用?? 操作员。
如果您正在处理字符串,请使用 if(String.IsNullOrEmpty(myStr))
您的代码示例将失败。 如果 obj 是 null 则 obj.ToString() 将导致 null 引用异常。 我会缩短该过程并在您的助手 function 的开头检查 null obj。 至于您的实际问题,您正在检查 null 或零的类型是什么? 在 String 上有一个很棒的 IsNullOrEmpty function,在我看来这将是一个很好的使用扩展方法来在 int 上实现 IsNullOrZero 方法? 类型。
编辑:记住,“?” 只是 INullable 类型的编译器糖,因此您可能会将 INullable 作为参数,然后将其与 null (parm == null)进行比较,如果不是 null 比较为零。
有没有更好的办法?
好吧,如果您真的在寻找更好的方法,您可能可以在 Rate 之上添加另一层抽象。 好吧,这是我刚刚想出的使用 Nullable 设计模式的东西。
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) { } } }
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);}}
}
不要忘记,对于字符串,您始终可以使用:
String.IsNullOrEmpty(str)
代替:
str==null || str==""
C#9:你可以写
if (item.Rate is null or 0)
使用 C# 7.0 或更高版本,您可以使用is
关键字将对象与如下模式匹配:(请参阅is 运算符 - C# 参考 | Microsoft )
if (item is { Rate: 0 or null })
{
// Do something
}
比Joshua Shannon的好回答更进一步。 现在防止装箱/拆箱:
public static class NullableEx
{
public static bool IsNullOrDefault<T>(this T? value)
where T : struct
{
return EqualityComparer<T>.Default.Equals(value.GetValueOrDefault(), default(T));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.