如何在嵌套引用中检查null

时间:2012-04-28 08:25:19

标签: c# c#-4.0 nullreferenceexception

寻找一些最佳实践指南。假设我有一行代码如下:

Color color = someOrder.Customer.LastOrder.Product.Color;

在正常情况下,Customer,LastOrder,Product和Color可能为null。但是,如果路径中的任何一个对象为null,我希望color为null;为了避免空引用异常,我需要检查每个对象的空条件,例如

Color color = someOrder == null ||
              someOrder.Customer == null || 
              someOrder.Customer.LastOrder == null ||
              someOrder.Customer.Product == null ? 
              null : someOrder.Customer.LastOrder.Product.Color;

或者我可以这样做

Color color = null;
try {color = someOrder.Customer.LastOrder.Product.Color}
catch (NullReferenceException) {}

第一种方法显然有效,但编码和更难阅读似乎更乏味。第二种方法有点容易,但对此使用异常处理可能不是一个好主意。

是否有另一种检查空值的快捷方式,并在必要时将null指定为颜色?或者在使用这种嵌套引用时如何避免NullReferenceExceptions的任何想法?

6 个答案:

答案 0 :(得分:10)

您正在寻找空安全解除引用运算符。

Color color = someOrder?.Customer?.LastOrder?.Product?.Color;

不幸的是C#不支持它。也许它会在稍后添加,但目前还没有计划这样做。

相关

答案 1 :(得分:1)

最佳做法是遵循Law of Demeter,听起来像:不要与陌生人交谈。即对象应该避免调用另一个方法返回的成员对象的方法。这允许编写更少耦合,更易于维护和可读的代码。

所以,避免使用someOrder.Customer.LastOrder.Product.Color之类的“火车残骸”,因为它们完全违反了得墨忒耳法则。甚至很难理解这段代码的商业含义。为什么你得到其他订单的产品颜色,这不是现在的订单?

可能的方法来消除火车残骸 - 推动功能更接近有趣的残骸结束。在您的情况下,还要考虑将最后一个产品传递给您的方法,而不是使用某些订单。

答案 2 :(得分:1)

你需要实现这一点。

用法

Color color = someOrder.ComplexGet(x => x.Customer.LastOrder.Product.Color);

Color color = Complex.Get(() => someOrder.Customer.LastOrder.Product.Color);

帮助程序类实现

public static class Complex
{
    public static T1 ComplexGet<T1, T2>(this T2 root, Func<T2, T1> func)
    {
        return Get(() => func(root));
    }

    public static T Get<T>(Func<T> func)
    {
        try
        {
            return func();
        }
        catch (Exception)
        {
            return default(T);
        }
    }
}

答案 3 :(得分:0)

我肯定更喜欢第一种方法......第二种方法利用程序流程的异常机制,这是不好的做法恕我直言......

AFAIK在C#中没有快捷方式或“空值安全解除引用运算符”。

答案 4 :(得分:0)

定义访问嵌套属性的唯一方法。 例如像这样

private Customoer GetCustomer(Order order)
{
  return order != null ? order.Customer : null;
}

private Order GetLastOrder(Customer customer)
{
   return customer != null ? customer.LastOrder : null;
}

使用已定义的方法访问应用程序中的属性

答案 5 :(得分:0)

您还可以在if语句中使用Null条件运算符。如果有很多嵌套值,则非常有用。

示例:

public class DummyDto
{
    public string Name { get; set; }

    public DummyDto Parent { get; set; }
}

class Program
{
    static void Main(string[] args)
    {

        var dummyDto = new DummyDto();

        //Both if statements will be true below
        if(dummyDto.Parent?.Name == null)
        {
            Console.WriteLine("DummyDto is null");
        }

        if (dummyDto.Parent == null || dummyDto.Parent.Name == null)
        {
            Console.WriteLine("DummyDto is null");
        }
    }
}