Nullsafe在c#中导航

Nir*_*hah 7 .net c# linq null

可能重复:
C#中的安全导航操作员?
"如果object为null,则为null;如果object为null,则为object.member"的快捷方式

在我的XML处理项目中,我必须浏览链式属性以获得所需的值.例如,obj1.obj2.obj3.obj4.obj....Value.并且可能退出此链中的任何对象为null.

我用Google搜索了"c#中的NullSafe导航"并找到了一些不错的文章.从Post之一,我有了实现自定义扩展的想法.现在我对这个扩展的性能有疑问.我有这3个解决方案.任何人都可以建议我采用哪一种(在性能方面)?

  • 选项1(使用本文中解释的逻辑):

    //custom extension method
    public static TOutput IfNotNull<TInput, TOutput>(this TInput x, Func<TInput, TOutput> f)
        where TInput : class
        where TOutput : class
    {
        return x == null ? null : f(x);
    }
    
    //with custom extension method -- Very neat & clean.. but what about performance? 
    string x = obj1
                .IfNotNull(x => x.obj2)
                .IfNotNull(x => x.obj3)
                .IfNotNull(x => x.obj4)
                .IfNotNull(x => x.obj5)
                .IfNotNull(x => x.Value);
    
    Run Code Online (Sandbox Code Playgroud)
  • 选项2:

    //with NullCheck  -- probably right way?
    if(obj1 != null 
        && obj1.obj2 != null 
        && obj1.obj2.obj3 != null 
        && obj1.obj2.obj3.obj4 != null
        && obj1.obj2.obj3.obj4.obj5 != null)
    {
        string x = obj1.obj2.obj3.obnj4.obj5.Value;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 2选项:

    //with try-catch.. With lowest cyclomatic complexity, but not a right approach.
    try
    {
        string x = obj1.obj2.obj3.obnj4.obj5.Value;
    }
    catch(NullReferenceException ne)
    {
        //ignore exception
    }
    
    Run Code Online (Sandbox Code Playgroud)

Pet*_*ter 3

我绝对不会选择 try-catch 选项。这不仅是一种代码味道(异常驱动开发),而且如果您担心性能,异常处理也不是正确的选择。

我不太明白第二个选项。您是否必须将其放在您想要访问 Value 属性的任何地方?或者是在扩展方法中。

选项一看起来最干净。

关于性能:我认为您不会发现选项 1 和 2 之间有很大差异,但您可以在一个小型控制台项目中尝试一下。只需运行第一个和第二个选项(例如 1000 次)并计算所需的时间。不是精确的科学,但通常足以衡量性能差异。

我猜你不会看到很大的区别。我认为您正在练习微优化。除非您要在一个确实很重要的系统上运行,否则请采用对您来说最优雅的解决方案。


归档时间:

查看次数:

864 次

最近记录:

15 年,1 月 前