返回此而不是无效是否有任何不利之处?

时间:2008-09-11 17:32:51

标签: .net fluent-interface

假设没有返回void,而是返回对该类的引用,即使它没有任何特定的语义意义。在我看来,它会给你更多关于如何调用方法的选项,允许你以流畅的界面风格使用它,我不能真正想到任何缺点,因为你不需要做任何事情带有返回值(甚至存储它)。

假设您处于想要更新对象然后返回其当前值的情况。 而不是说

myObj.Update();
var val = myObj.GetCurrentValue();

你可以将这两行结合起来说

var val = myObj.Update().GetCurrentValue();

编辑:我突然问起以下问题,回想起来,我同意这可能是不必要的和复杂的,但是我的问题是关于归还这个而不是无效。

在相关的说明中,你们怎么看待这种语言包括一些新的语法糖:

var val = myObj.Update()<.GetCurrentValue();

此运算符的优先级较低,因此myObj.Update()将首先执行,然后在myObj上调用GetCurrentValue()而不是Update的void返回。

基本上我正在想象一个操作员会说“在左边的第一个有效对象上调用操作员右侧的方法”。有什么想法吗?

7 个答案:

答案 0 :(得分:12)

我认为作为一般政策,它根本没有意义。以这种方式链接的方法适用于正确定义的接口,但只有在它具有语义意义时才适用。

你的例子是一个不合适的例子,因为它没有语义意义。

同样,使用设计合理的流畅界面也不需要你的语法糖。

流畅的界面或方法链 可以很好地工作,但需要仔细设计。

答案 1 :(得分:9)

我在Java中知道他们实际上正在考虑为void方法制定这种标准行为。如果你这样做,你不需要额外的语法糖。

我能想到的唯一不利因素是表现。但这很容易衡量。我会在几分钟内回复你的结果: - )

编辑:

返回引用比返回void慢一点..真是一个惊喜。所以这是唯一的缺点。在调用你的函数时还需要几个滴答。

答案 2 :(得分:3)

这不是“流畅的接口” - 就像JQuery使用的那样 - 是如何构建的?一个好处应该是代码可读性(尽管http://en.wikipedia.org/wiki/Fluent_interface的维基百科条目提到有些人发现 NOT 可读)。另一个好处是代码简洁,你不需要在7行代码中设置属性,然后在第8行调用该对象的方法。

Martin Fowler(他在这里创造了这个术语 - http://martinfowler.com/bliki/FluentInterface.html)说,除了方法链接之外,还有更多流畅的接口,但是方法链接是一种与流畅接口一起使用的常用技术。

编辑: 我实际上回到这里编辑我的答案并补充说,当我看到乔治的评论指出我确实忘记讨论时,以任何可衡量的方式返回此而不是虚空是没有缺点的。这个问题。对不起,最初的“毫无意义”漫无边际。

答案 3 :(得分:2)

返回“self”或“this”是一种常见模式,有时也称为"method chaining"。至于你提出的语法糖,我不太确定。我不是一个.NET人,但它对我来说似乎并不十分有用。

答案 4 :(得分:2)

NeXTSTEP Objective-C框架曾用于使用此模式。一旦分布式对象(基本上是远程过程调用)被添加到语言中,它就会在该框架中停止 - 返回self的函数必须是同步调用,因为分布式对象系统看到了返回类型并假设调用者需要知道函数的结果。

答案 5 :(得分:2)

我能看到的唯一缺点是它使API稍微混乱。假设您有一些带有remove()方法的集合对象,该方法通常会返回void。现在您想要返回对集合本身的引用。新签名看起来像:

public MyCollection remove(Object someElement)

只是查看签名,您不清楚是否返回对同一实例的引用。也许MyCollection是不可变的,你正在返回一个新实例。在某些情况下,就像这里一样,您需要一些外部文档来澄清这一点。

我实际上喜欢这个想法,我相信在改进Java7中的所有void方法时都会有一些关于返回对'this'的引用的讨论,但它最终落空了。

答案 6 :(得分:0)

乍一看它可能看起来不错,但是对于一致的界面,你需要所有方法都返回对它的引用(它有自己的问题)。

假设您有一个类,其中有两个方法GetA返回此方法,而GetB返回另一个方法:

然后你可以调用obj.GetA()。GetB(),但不能调用obj.GetB()。GetA(),这至少看起来不一致。

使用Pascal(和Visual Basic),您可以调用同一对象的多个方法。

with obj
  .GetA();
  .GetB();
end with;

此功能的问题在于您可以轻松编写比应该更难理解的代码。另外添加一个新运算符可能会让它变得更难。