返回此值而不是void,有什么缺点吗?(涉及IT技术)

12

假设在一个方法中,你返回了一个类的引用而不是返回void,即使这样做并没有特别的语义意义。我认为这样做会给你更多调用方法的选项,允许你以流畅接口的方式使用它,而且我想不出任何缺点,因为你不必对返回值进行任何操作(甚至不必存储它)。

那么,假设你处于一种情况下,想要更新一个对象,然后返回其当前值。与其说

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

你将能够将这两行代码组合起来,以此表达

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

编辑:我冲动地提出了下面的问题,回过头来看,我同意它很可能是不必要和复杂化的,但是我的问题是关于返回这个而不是void的。

另外,你们对语言中包含一些新的语法糖有什么想法?

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

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

本质上,我想象中的运算符是这样说的:“在左侧第一个有效对象上调用右侧运算符上的方法”。有什么想法吗?

7个回答

12

我认为作为一般政策,这根本没有意义。以这种方式进行方法链接只有在适当定义接口的情况下才能起作用,但仅当它具有语义意义时才是合适的。

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

同样,如果设计了良好的流畅接口,你的语法糖是不必要的。

流利的界面或方法链接可以很好地工作,但需要小心设计。


方法链的优点是可以避免定义本地变量的使用,这是一个好的实践(如果不过度使用)。 - Keith Pinson

10

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

我能想到的唯一缺点是性能。但这很容易衡量。我会在几分钟内给您带来结果:-)

编辑:

返回引用比返回void慢..真是个惊喜。所以这是唯一的缺点。调用函数时多了几个滴答声。


Smalltalk很棒,尽管你不能像其他语言那样优雅地进行方法链接。 - Roman A. Taycher

3

我唯一看到的缺点是它会使API稍微更加混乱。比如说,你有一个带有remove()方法的集合对象,通常该方法返回void。现在你想返回对集合本身的引用。新的签名将如下所示:

public MyCollection remove(Object someElement)

仅从签名上看,不清楚您是否返回对同一实例的引用。也许MyCollection是不可变的,并且您正在返回一个新实例。在某些情况下,例如此处,您需要一些外部文档来澄清这一点。

我实际上很喜欢这个想法,并且我相信在Java7中重新配置所有void方法以返回对“this”的引用进行了一些讨论,但最终失败了。


这是正确的,但它也允许您编写简化的代码,例如myCollection.remove(item1).add(item2).swap(item3, item4)。 - George Mauer

3
这不就是“流畅接口”(如JQuery所使用的)的构建方式吗?其中一个好处应该是代码可读性(尽管维基百科条目http://en.wikipedia.org/wiki/Fluent_interface提到有些人认为它不可读)。另一个好处在于代码简洁,你失去了在7行代码中设置属性,然后在第8行调用该对象上的方法的需要。
马丁·福勒(在此处创造了这个术语 - http://martinfowler.com/bliki/FluentInterface.html)表示,流畅接口不仅仅是方法链接,但方法链接是与流畅接口一起使用的常见技术。
编辑:实际上,我回来编辑我的答案,并添加返回它而不是void没有任何可衡量的劣势,当我看到乔治的评论指出我忘记讨论问题的点。抱歉最初的“无意义”的胡言乱语。

是的,这就是我提到了流畅接口式样的原因,正如你所说,流畅接口比方法链更复杂。问题是,这是否真的有任何劣势。 - George Mauer

2

返回"self"或"this"是一种常见的模式,有时被称为"方法链接"。至于您提出的语法糖,我不太确定。虽然我不是.NET工程师,但它似乎对我没有太大用处。


是的,也许不是运算符的想法,但我仍然很想知道返回void相比于这个有哪些好处 - George Mauer

2
NeXTSTEP Objective-C框架曾经使用过这种模式。随着语言添加远程过程调用(基本上是分布式对象),该模式在该框架中已被停止使用,因为返回self的函数必须是同步调用,因为分布式对象系统看到返回类型并假定调用者需要知道函数的结果。

我能理解那可能是个问题,但在C#或VB代码中并不是限制。 - George Mauer
理论上,任何支持内省的编程语言都可能存在这个问题。 - John Calsbeek

0

乍一看可能会很好,但为了一个一致的接口,你将需要所有方法都返回对 this 的引用(这本身就有问题)。

假设你有一个类,其中包含两个方法 GetA 返回 this,GetB 返回另一个对象:

那么你可以调用 obj.GetA().GetB(),但不能调用 obj.GetB().GetA(),至少看起来不太一致。

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

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

这个特性的问题在于你很容易编写比本应更难理解的代码,同时添加一个新的操作符可能会让它变得更加困难。


首先,如果一个方法名为GetA()却返回void类型的话,那就很奇怪了。一个更合理的例子是obj.UpdateA().GetA(),这对我来说非常有意义。 - George Mauer
一个问题 - obj.GetA() 返回 A 不是更有意义吗?这样做不会牺牲可读性吗? - Subramanian
你对这个例子过于深究了。´this´可能是´A´类型,所以´GetA´返回´this´是完全有道理的。 - Ismael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接