3

我想知道使用扩展方法来避免检查层次结构中的空值。这个例子:

// GetItems(), GetFirstOrDefault(), GetProduct(), GetIDProduct() are extension methods like:
public static SomeType GetSomeProperty( this XYZ obj ) {
    if ( object.ReferenceEquals( obj, null ) ) { return default( SomeType ); }
    return obj.SomeProperty;
}

// the code with extension methods
Guid? idProduct = this.Invoice.GetItems().GetFirstOrDefault().GetProduct().GetIDProduct();
// instead of
Guid? idProduct = null;
Invoice invoice = this.Invoce;
if ( null != invoice ) {
    InvoiceItems items = invoice.Items;
    if ( null != items && items.Count > 0 ) {
        InvoiceItem item = items[0];
        if ( null != item ) {
            idProduct = item.IDProduct();
        }
    }
}

我知道,有可用的空对象模式,但这种类型的扩展方法的解决方案看起来更好。

你认为,这个解决方案是好是坏(因为坏/好的设计、清晰度,等等)?

请投票“好”或“坏”,你为什么这么认为。帖子被标记为社区。

4

5 回答 5

2

我会理智地做这件事:

Guid? idProduct = null;
Invoice invoice = this.Invoce;

if (invoice != null && 
    invoice.Items != null &&
    invoice.Items.Count > 0 &&
    invoice.Items[0] != null) 
{
   idProduct = invoice.Items[0].IDProduct();
}
于 2008-11-15T13:57:40.867 回答
1

打破了实例方法的语义。扩展方法对调用者来说就像实例方法,因此应该表现得像它们。当你像这样破坏语义时,代码将更难理解和维护,它的行为会让大多数开发人员感到惊讶。

于 2010-02-04T14:05:26.013 回答
1

我将其投票为“对该解决方案不感兴趣”。

我对我的实体模型类的 Null-Object-Pattern 很好。

于 2010-02-04T14:08:17.617 回答
0

阅读这段代码时,首先让我印象深刻的是

GetFirstOrDefault().GetProduct()

它打破了两个习惯用法:1)使用GetJon 指出的样式方法,以及 2)“取消隐藏” Null Object 提供的抽象。这OrDefault让我成为你代码的读者,让我思考在null哪里

GetFirst().GetProduct()

不会。是的,Null Object 和您的扩展方法替代方案的要点之一是减轻读者和/或维护者的负担。否则为什么要这样做?

于 2011-10-25T03:03:45.317 回答
0

Java 和 .net 的一个限制是,没有什么可以清楚地确定引用类型的存储位置是否应该在语义上被视为持有对象的值,而不是识别对象(当然,从计算机的角度来看,所有这些存储位置都可以后者)。尽管如此,有些类型(如String)的存储位置通常会被视为保存值,而其他类型(如StringBuilder)的存储位置将被视为标识应对其执行操作的对象。

如果不是对 的struct约束Nullable<T>,并且如果类类型可以指定实例成员this在空对象上调用时应该运行(为空),我会认为这对于某些类型来说是一个很好的模式。虽然通常不可能合理地为可变类类型指定默认值,但对于许多不可变类型来说,具有合理的默认行为(例如default(string).Length可以返回零)是完全合理的。不幸的是,.net 语言没有指定属性和方法应该可用于空对象的方法,但至少扩展方法可以在这个方向上有所帮助。

于 2012-10-03T18:07:05.023 回答