c# - 当这些属性的父级可以或不可以为null时,返回null属性的默认值

时间:2013-05-13 14:37:57

标签: c# lambda null-object-pattern

所以我没有找到任何优雅的解决方案,谷歌搜索或整个stackoverflow。我想我的手中有一个非常具体的情况,无论如何它在这里:

我有一个我无法控制的对象结构,因为我从外部WS接收这个结构。这是一个非常庞大的对象,具有不同级别的字段和属性,并且此字段和属性在任何级别都可以为null或不为null。您可以将此对象视为贫血模型,它没有行为,只是状态。

出于这个问题的目的,我会给你一个模拟我情况的简化样本:

Class A
  PropB1
    PropC11
      PropLeaf111
    PropC12
      PropLeaf112
  PropB2
    PropC21
      PropLeaf211
    PropC22
      PropLeaf221

因此,在我的代码中,我必须在不同级别访问许多这些属性,以便进行一些数学计算以计算我需要的内容。基本上对于我必须做的每种类型的计算,我必须测试我需要的每个属性级别,以检查它是否不为空,在这种情况下我将返回(十进制)0,或任何其他默认值取决于业务逻辑。

我必须要做的数学示例:

var value = 0;
if (objClassA.PropB1 != null && objClassA.PropB1.PropC11 != null) {
  var leaf = objClassA.PropB1.PropC11.PropLeaf111;
  value = leaf.HasValue ? leaf.Value : value;
}

就是这样,这个结构的叶子属性总是原始的,或者是可以为空的原语,在这种情况下我会给予适当的处理。这是我必须为我需要的每个属性做的“逻辑”,有时我必须使用它们中的一些。此外,真正的结构非常大,因此我需要做的验证数量对于每个必要的属性也会更大。

现在,我提出了一些想法,我认为这些想法都不理想:

  1. 创建收集属性的方法,抽象任何必要验证的方法,或获取默认值的逻辑。缺点是,在我看来,它会有一些重复的代码,因为对于某些字段组,验证和默认值会相似。
  2. 创建一个通用方法,它接收一个对象,以及一个访问所需字段的lamba函数。此方法将尝试执行该函数并返回其结果,并且在NullReferenceException的情况下,它将返回默认值。这一方面的好处是,它是真正的通用,我只需要传递lambdas来访问属性,该方法将处理任何问题。它的缺点是,我正在使用try - >捕获控制逻辑,这不是它的目的,代码可能看起来让其他最终会给它维护的程序员感到困惑。
  3. 空对象模式,我猜这将是最优雅的解决方案。如果是正常情况,那将有所有好处。但问题是为这个结构提供Null Objects的影响。只是为了给出一些上下文,我正在处理的软件,与政府的服务集成,我正在使用的结构,在政府的规范中,有一些领域,其中null有一些不同于默认值,如“0”。此规范也会不时更改,并且会再次生成类,并且我必须要创建Null对象的后期处理也需要维护,这对我来说似乎有点危险。
  4. 我希望自己足够清楚。

    提前致谢。

    解决方案

    根据接受的答案,这是对我如何解决问题的回应。

    我对C#很陌生,这种链接的讨论确实帮助我在很多方面提出了一个优雅的解决方案。我仍然有一个问题,根据代码的执行位置,它使用.NET 2.0,但我也找到了解决这个问题的方法,我可以在某种程度上定义扩展方法:https://stackoverflow.com/a/707160/649790

    对于解决方案本身,我发现这个最好: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad

    我基本上可以通过这种方式访问​​属性,只需进行数学运算:

    objClassA.With(o => o.PropB1).With(o => PropC11).Return(o => PropLeaf111, 0);
    

    对于我需要的每个房产。它仍然不仅仅是:

    objClassA.PropB1.PropC11.PropLeaf111
    
    当然,但是到目前为止我发现的任何解决方案要好得多,因为我不熟悉扩展方法,我真的学到了很多东西。

    再次感谢。

1 个答案:

答案 0 :(得分:4)

有一个处理此问题的策略,涉及"Maybe" Monad

基本上它的工作原理是提供一个“流畅的”界面,其中属性链被链上某处的null中断。

请点击此处查看示例:http://smellegantcode.wordpress.com/2008/12/11/the-maybe-monad-in-c/

还在这里:

http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad http://mikehadlow.blogspot.co.uk/2011/01/monads-in-c-5-maybe.html

它与您似乎需要的相关但不完全相同;但是,也许它可以适应您的需求。这些概念非常基础。