可空类型:在c#中检查null或0的最佳方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可空类型:在c#中检查null或0的最佳方法相关的知识,希望对你有一定的参考价值。

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

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)){} //但你从中得不到多少

另一答案

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

String.IsNullOrEmpty(str)

代替:

str==null || str==""
另一答案

距离Joshua Shannon的漂亮answer更进了一步。现在防止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));
    }
}
另一答案

使用泛型:

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将与nulldefault(T))进行比较,否则,如果Tvalue type,让我们说双倍,default(t)是0d,因为bool是false,因为char是''等等......

另一答案

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

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

这个解决方案


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

另一答案

这只是弗雷迪里奥斯仅使用泛型的接受答案的扩展。

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)是否为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
另一答案

我同意使用??运营商。

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

另一答案

有没有更好的办法?

好吧,如果你真的在寻找更好的方法,你可以在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) { }
    }
}
另一答案

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

编辑:记住,'?'只是INullable类型的编译器糖,所以你可以把一个INullable作为parm,然后jsut将它与null(parm == null)进行比较,如果不是null则比较为零。

另一答案
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);}}
}

以上是关于可空类型:在c#中检查null或0的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

可空类型:在 c# 中检查空或零的更好方法

何时在启用可空引用类型的情况下对参数进行空检查

避免可空值类型的 Value 属性?

Kevin Learn Kotlin:空指针检查

int c=8;和int? c=8;有啥区别,作用是?

? 的可空类型问题:条件运算符