Question

Let us say for a moment that C# allowed multiple return values in the most pure sense, where we would expect to see something like:

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

compacted to:

string sender, receiver = message.GetParticipants();

In that case, I do not have to understand the return values of the method until I actually make the method call. Perhaps I rely on Intellisense to tell me what return value(s) I'm dealing with, or perhaps I'm searching for a method that returns what I want from a class I am unfamiliar with.

Similarly, we have something like this, currently, in C#:

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

where the argument to GetParticipants is an out string parameter. However, this is a bit different than the above because it means I have to preempt with, or at least go back and write, code that creates a variable to hold the result of the out parameter. This is a little counterintuitive.

My question is, is there any syntactic sugar in current C#, that allows a developer to make this declaration in the same line as the method call? I think it would make development a (tiny) bit more fluid, and also make the code more readable if I were doing something like:

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

to show that receiver was being declared and assigned on the spot.

Was it helpful?

Solution

No, there isn't currently any syntactic sugar around this. I haven't heard of any intention to introduce any either.

I can't say I use out parameters often enough for it really to be a significant concern for me (there are other features I'd rather the C# team spent their time on) but I agree it's a bit annoying.

OTHER TIPS

.NET 4 will be adding a Tuple concept, which deals with this. Unfortunately, the C# language isn't going to provide any language support for "destructuring bind".

Personally, I like the inconvience introduced when using out parameters. It helps me to think about whether my method is really doing what it should be or if I've crammed too much functionality into it. That said, perhaps dynamic typing in C#4.0/.Net 4 will address some of your concerns.

dynamic participant = message.GetParticipants();

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

where

public object GetParticipants()
{
     return new { Sender = ..., Recipient = ... };
}

You can also return a Tuple<T,U> or something similar. However, since you want to return two string, it might get confusing.

I use the Tuples structs of the BclExtras library which is very handy (found it on SO, thank you JaredPar!).

I don't think such functionality exists, but if it were implemented in a way similar to arrays in perl that could be useful actually.

In perl You can assign an array to a list of variables in parentheses. So you can for example do this

($user, $password) = split(/:/,$data);

Where this bugs me the most: since there's no overload of (say) DateTime.TryParse that doesn't take an out parameter, you can't write

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.

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

int.TryParse(s, out var x);

At best you would have to use var rather than an explicit type, unless you want to restrict all multiple return values to be of the same type (not likely practical). You would also be limiting the scope of the variable; currently you can declare a variable at a higher scope and initialize it in an out parameter. With this approach, the variable would go out of scope in the same block as its assignment. Obviously this is usable in some cases, but I wouldn't want to enforce this as the general rule. Obviously you could leave the 'out' option in place, but chances are people are going to code for one approach or the other.

I think this is not what you want. You may have come across a piece of code where you would have liked that. But variables popping out of nowhere because they have been introduced in the parameter list would be a personal nightmare ( to me :) )

Multiple return values have grave downsides from the point of portability/maintainability. If you make a function that returns two strings and you now want it to return three, you will have to change all the code that uses this function. A returned record type however usually plays nice in such common scenarios.

you may be opening pandora's box ;-)

For line compacting:

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

Lines can be any length, so you could pack some common stuff into one. Just try to live with the semicolons.

Try the following code

Participants p = message.GetParticipants();
log(p.sender,p.receiver);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top