8

让我们说一下,C# 在最纯粹的意义上允许多个返回值,我们希望看到类似的东西:

string sender = message.GetSender();
string receiver = message.GetReceiver();

压缩为:

string sender, receiver = message.GetParticipants();

在这种情况下,在我实际调用方法之前,我不必了解方法的返回值。也许我依靠 Intellisense 来告诉我我正在处理什么返回值,或者我正在寻找一种方法来从我不熟悉的类中返回我想要的东西。

同样,我们目前在 C# 中有这样的东西:

string receiver;
string sender = message.GetParticipants(out receiver);

其中 GetParticipants 的参数是一个输出字符串参数。然而,这与上面的有点不同,因为这意味着我必须抢占,或者至少回去写,创建一个变量来保存 out 参数的结果的代码。这有点违反直觉。

我的问题是,当前 C# 中是否有任何语法糖允许开发人员在与方法调用相同的行中进行此声明?我认为这会使开发(微小)更加流畅,并且如果我正在执行以下操作,也会使代码更具可读性:

string sender = message.GetParicipants(out string receiver);

以表明接收者正在当场宣布和分配。

4

10 回答 10

9

不,目前没有任何语法糖。我也没有听说有任何介绍的打算。

我不能说我使用out参数的次数足够多,以至于这对我来说确实是一个重要的问题(我希望 C# 团队花时间在其他功能上),但我同意这有点烦人。

于 2009-04-14T16:57:27.720 回答
5

.NET 4 将添加一个处理此问题的元组概念。不幸的是,C# 语言不会为“解构绑定”提供任何语言支持。

于 2009-04-14T17:08:04.590 回答
4

就个人而言,我喜欢使用 out 参数时带来的不便。它可以帮助我思考我的方法是否真的在做它应该做的事情,或者我是否在其中塞入了太多的功能。也就是说,也许 C#4.0/.Net 4 中的动态类型会解决您的一些问题。

dynamic participant = message.GetParticipants();

var sender = participant.Sender;
var recipient = participant.Recipient;

在哪里

public object GetParticipants()
{
     return new { Sender = ..., Recipient = ... };
}
于 2009-04-14T17:16:30.963 回答
2

您也可以返回 aTuple<T,U>或类似的东西。但是,由于您要返回两个字符串,因此可能会令人困惑。

我使用非常方便的BclExtras 库的元组结构(在 SO 上找到它,谢谢 JaredPar!)。

于 2009-04-14T17:10:13.397 回答
2

我认为不存在这样的功能,但如果它以类似于 perl 中的数组的方式实现,那实际上可能很有用。

在 perl 中,您可以将数组分配给括号中的变量列表。所以你可以例如这样做

($user, $password) = split(/:/,$data);
于 2009-04-14T17:24:59.323 回答
2

这最让我烦恼的地方:因为没有(比如说)DateTime.TryParse不带out参数的重载,所以你不能写

if (DateTime.TryParse(s, out d))
{
   return new ValidationError("{0} isn't a valid date", s);
}

without declaring d. I don't know if this is a problem with out parameters or just with how the TryParse method is implemented, but it's annoying.

于 2009-04-14T18:18:04.780 回答
2

This syntactic sugar is now is now available in the roslyn preview as seen here (called Declaration expressions).

int.TryParse(s, out var x);
于 2014-04-16T18:21:30.750 回答
0

充其量您必须使用var而不是显式类型,除非您想将所有多个返回值限制为相同类型(不太可能)。您还将限制变量的范围;目前,您可以在更高的范围内声明一个变量并在 out 参数中对其进行初始化。使用这种方法,变量将超出与其赋值相同的块中的范围。显然这在某些情况下是可用的,但我不想将其作为一般规则强制执行。显然,您可以保留 ' out' 选项,但人们可能会为一种方法或另一种方法编写代码。

于 2009-04-14T16:55:46.460 回答
-1

试试下面的代码

Participants p = message.GetParticipants();
log(p.sender,p.receiver);
于 2009-04-14T17:04:23.600 回答
-1

我认为这不是你想要的。您可能遇到过一段您会喜欢的代码。但是变量突然出现,因为它们已被引入参数列表中,这将是个人的噩梦(对我来说:))

从可移植性/可维护性的角度来看,多个返回值具有严重的缺点。如果您创建了一个返回两个字符串的函数,而您现在希望它返回三个字符串,您将不得不更改所有使用该函数的代码。然而,返回的记录类型通常在此类常见场景中表现良好。

你可能正在打开潘多拉的盒子;-)

对于线压缩:

string s1, s2; s1 = foo.bar(s2);

行可以是任意长度,因此您可以将一些常见的东西打包成一个。试着忍受分号。

于 2009-04-14T17:07:45.493 回答