扩展方法而不是空对象模式
我想知道使用扩展方法来避免检查层次结构中的 null 。 示例:
// 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();
}
}
}
我知道,有可用的空对象模式,但使用此类扩展方法的解决方案看起来更好。
您认为这个解决方案是好还是坏(因为设计不好/好、清晰度等等)?
请投票“好”或“坏”,以及您为什么这么认为。 帖子被标记为社区。
I'm wondering to using extension method to avoid checking for null in hierarchy.
The example:
// 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();
}
}
}
I know, there is available Null Object pattern, but the solution with this type of extension methods looks better.
Do you think, this solution is good or bad (because bad/good design, lucidity, whatever else)?
Please vote "Good" or "Bad" and why do you think so.
Posts are flaged as community.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我会理智地做这件事:
I'd just do it sanely:
我将此投票为“对该解决方案不感兴趣”。
我对我的实体模型类使用空对象模式很满意。
I vote this as "not-interested-in-that-solution".
I'm fine with a Null-Object-Pattern for my entity model classes.
这破坏了语义实例方法。 对于调用者来说,扩展方法看起来像实例方法,因此应该像它们一样表现。 当你像这样破坏语义时,代码将更难理解和维护,它的行为会让大多数开发人员感到惊讶。
This breaks the semantics of an instance method. Extension methods look like instance methods to the callers, and as such should behave like them. When you break semantics like this, the code will be harder to understand and maintain, its behavior will surprise most developers.
阅读这段代码时,让我印象深刻的第一件事是
它打破了两个习惯用法:1)使用 Jon 指出的 Get 风格方法,2)“取消隐藏”Null Object 提供的抽象。
OrDefault
让我成为代码的读者,并让我思考null
,而不会。 是的,空对象和扩展方法替代方案的要点之一是减轻读者和/或维护者的负担。 否则为什么要这样做呢?
The first thing that struck me when reading this code was
It breaks two idioms: 1) using
Get
style methods as noted by Jon, and 2) "unhiding" the abstraction provided by Null Object. TheOrDefault
engages me as a reader of your code and makes me think aboutnull
wherewould not. And yes, one of the points of Null Object and your extension method alternative are to unburden the reader and/or maintainer. Or else why do either?
Java 和 .net 的一个限制是,没有任何内容可以清楚地标识引用类型的存储位置在语义上是否应被视为保存对象的值,而不是识别对象(当然,从计算机的角度来看,所有此类存储位置都是后者)。 尽管如此,有些类型(如
String
)的存储位置通常被视为保存一个值,而其他类型(如StringBuilder
)的存储位置通常被视为保存值。被视为识别应对其执行操作的对象。如果不是因为
Nullable
上的struct
约束,并且类类型可以指定实例成员应该运行(this
为 null) )当在空对象上调用时,我认为这是某些类型的绝佳模式。 虽然通常不可能明智地为可变类类型指定默认值,但对于许多不可变类型来说,具有合理的默认行为是完全合理的(例如,default(string).Length
可能返回零) 。 不幸的是,.net 语言没有办法指定属性和方法应该可用于 null 对象,但至少扩展方法可以在这方面提供一些帮助。One limitation with Java and .net is that there's nothing which clearly identifies whether a storage location of reference type should be regarded semantically as holding an object's value, versus identifying an object (from the computer's perspective, of course, all such storage locations do the latter). Nonetheless, there are some types (like
String
) for which a storage location would normally be regarded as holding a value, and others (likeStringBuilder
) for which a storage location would be regarded as identifying an object upon which operations should be performed.Were it not for the
struct
constraint onNullable<T>
, and if class types could specify that instance members should run (withthis
being null) when invoked on a null object, I would regard that as an excellent pattern for some types. While it's generally not possible to sensibly specify a default value for a mutable class type, for many immutable types it would be entirely reasonable to have sensible default behavior (e.g.default(string).Length
could return zero). Unfortunately, .net languages do not have a means of specifying that properties and methods should be usable on null objects, but at least extension methods can help a little in that direction.