95

我正在做一个项目,我发现我在很多很多地方检查以下内容:

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);
}

有没有更好的办法?

4

13 回答 13

176

我喜欢if ((item.Rate ?? 0) == 0) { }

更新1:

您还可以定义一个扩展方法,例如:

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

并像这样使用它:

if(item.IsNullOrValue(0)){} // 但你并没有从中得到太多

于 2009-03-11T04:08:26.587 回答
46

虽然我很喜欢接受的答案,但我认为,为了完整起见,也应该提到这个选项:

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

这个解决方案


¹但这不应该影响您的决定,因为这些类型的微优化不太可能产生任何影响。

于 2013-03-15T13:32:36.250 回答
44

使用泛型:

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是 a value type,假设为 double,default(t)则为 0d,对于 bool 是false,对于 char 是'\0'等等...

于 2009-03-11T04:39:24.470 回答
19

这实际上只是 Freddy Rios 仅使用泛型接受的答案的扩展。

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));
}

注意我们不需要检查 default(T) 是否为 null,因为我们正在处理值类型或结构!这也意味着我们可以安全地假设 T valueToCheck 不会为空;还记得那个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
于 2009-03-11T06:13:17.660 回答
2

我同意使用 ?? 操作员。

如果您正在处理字符串,请使用 if(String.IsNullOrEmpty(myStr))

于 2009-03-11T04:11:29.123 回答
2

您的代码示例将失败。如果 obj 为 null,则 obj.ToString() 将导致 null 引用异常。我会缩短该过程并在您的辅助函数开始时检查 null obj。至于您的实际问题,您要检查的类型是 null 还是零?在 String 上有一个很棒的 IsNullOrEmpty 函数,在我看来这将是一个很好的使用扩展方法来在 int 上实现 IsNullOrZero 方法?类型。

编辑:记住,“?” 只是 INullable 类型的编译器糖,因此您可以将 INullable 作为参数,然后将其与 null (parm == null) 进行比较,如果不是 null,则与零进行比较。

于 2009-03-11T04:14:47.617 回答
2

有没有更好的办法?

好吧,如果您真的在寻找更好的方法,您可能可以在 Rate 之上添加另一层抽象。好吧,这是我刚刚想出的使用 Nullable 设计模式的东西。

使用系统;
使用 System.Collections.Generic;

命名空间 NullObjectPatternTest
{
    公开课程序
    {
        公共静态无效主要(字符串[]参数)
        {
            var items = 新列表
                            {
                                新项目(RateFactory.Create(20)),
                                新项目(RateFactory.Create(空))
                            };

            PrintPricesForItems(项目);
        }

        私有静态无效 PrintPricesForItems(IEnumerable 项目)
        {
            foreach (var item in items)
                Console.WriteLine("商品价格:{0:C}", item.GetPrice());
        }
    }

    公共抽象类 ItemBase
    {
        公共抽象费率{得到; }
        公共 int GetPrice()
        {
            // 无需检查 Rate == 0 或 Rate == null
            返回 1 * Rate.Value;
        }
    }

    公共类项目:ItemBase
    {
        私有只读速率_Rate;
        公共覆盖率率 { 得到 { 返回 _Rate; } }
        公共项目(费率){ _Rate = 费率;}
    }

    公共密封类 RateFactory
    {
        公共静态速率创建(int?rateValue)
        {
            如果 (!rateValue || rateValue == 0)
                返回新的 NullRate();
            返回新的速率(rateValue);
        }
    }

    公开课率
    {
        公共 int 值 { 获取;放; }
        public virtual bool HasValue { get { return (Value > 0); } }
        公共利率(整数值){价值=价值;}
    }

    公共类 NullRate : 率
    {
        公共覆盖 bool HasValue { get { return false; } }
        公共 NullRate() : 基数(0) { }
    }
}
于 2009-03-11T04:50:11.730 回答
1

C#9:你可以写

if (item.Rate is null or 0)
于 2021-11-29T11:48:07.320 回答
0
public static bool nz(object obj)
{
    return obj == null || obj.Equals(Activator.CreateInstance(obj.GetType()));
}
于 2009-03-11T04:11:23.773 回答
0
class Item{  
 bool IsNullOrZero{ get{return ((this.Rate ?? 0) == 0);}}
}
于 2009-03-11T04:15:46.540 回答
0

不要忘记,对于字符串,您始终可以使用:

String.IsNullOrEmpty(str)

代替:

str==null || str==""
于 2009-03-11T05:14:16.117 回答
0

使用 C# 7.0 或更高版本,您可以使用is关键字将对象与这样的模式匹配:(请参阅is 运算符 - C# 参考 | Microsoft

if (item is { Rate: 0 or null })
{
  // Do something
}
于 2022-02-04T07:46:05.310 回答
-1

比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));
    }
}
于 2018-10-19T07:37:31.307 回答