Multiple return values, I want this in C#

I so badly want to have support for multiple return values in C# instead of using out parameters.

Note: The following is only an example, we can use a struct or an object to create a data structure which will hold the value, but I only use this code for demonstration purpose.

int x,y,z;
bool isHidden;

GetCords("MyElement", out x, out y, out z, out isHidden);


Instead of the code above, I want to do something like this:

Return 10,11,10,true;

var x,y,z,isHidden = GetCords("MyElement");

If I don’t care about the y and z return values I can instead write:

var x,,,isHidden = GetCords("MyElement");

Isn’t this beautiful?

hmm,  when I’m thinking of beauty, I start to think about "The beauty is in the eye of the beholder" ;)

To confess something, the language LUA support this and I loved it when I created an add-on for World Of Warcraft.

32 Comments

  • Your note says it all. Why waste valuable time on creating something while there are far more elegant, easy to implement, solutions available?

  • Hi Fredrik,

    I have designed something that will let you get as close as humanly possible to this using C# ;-)

    Probably gets you 90% to where you want regarding multiple return values and is strongly typed, etc.

    I will blog shortly :-)

    Regards,

    David Taylor


  • JV:
    You don't want to create a sturct or object to hold information every time you want a method to return multiple values, trust me ;)
    There are situation where a struct or object will only create some extra overhead and code.. for example think of the Membership.CreateUser method shipped with ASP.Net. It returns a MembershipUser if it succeed to create the user, it also have an output variable with the create status. Instead of using the out parameter we could write:
    var membershipUser, createStatus = Membership.CreateUser("Name","Password");


  • David Taylor:
    I look forward to see it :)
    We can sort of do it with anonymous types:
    public object GetSomething()
    {
       return new { x = 10, y = 11, isHidden = true };
    }
    But we need to use reflection to get the values.A person from the C# Team have the multiple return values as his favorite, so I hope he will make sure they will add something similar ;)

  • You are correct that anonymous types are great but not the solution for multiple return values. Of course as soon as you start using reflection you give up your strong typing.

    I will post what I have worked on shortly :-)

    Davide

  • some 'legacy' languages like LISP & APL can perform the elegance you are looking for.

  • Why? doesnt this breake the laws of oo and ddd


  • Donald:
    I can’t see why? It depends how you want to use it, for example today you can use out parameters. You can also with LINQ use Data Projection etc. This suggestion is a way to get rid of the out parameters and have one common way to let a method returns multiple values, instead of using return and out parameters.

  • If you for some reason want this , then i think your design needs some remodeling.



  • C# is a hybrid, isn’t a 100% pure only OO language. The out parameters have only one purpose in C#, it’s a way to return multiple values and why shouldn’t the values be returned the normal way with "return"? There are several methods today (Helper methods, Framework method which have multiple return values but they use out parameters). A parameter for me shouldn’t be used to return a value; it should be used to pass in a value. The Return statement should return the value.
    If I have a simple helper method added to my “Infrastructure” which should return x and y coordinates I need to do something like this:
    Public struct Point
    {
          public double X;
          public double Y;
    }
    Point point = GetCords(“MyElement”);
    Or:
    double x;
    double y;
    GetCords(“MyElement”, out x, out y);
    Well I prefer the first solution. But the only thing I need to know is the value of x and y and this is a simple helper method. So why not skip the Point Struct and instead do:
    double x,y = GetCords(“MyElement”);
    If you don’t like it, it’s fine with me. But I’m a lazy programmer and don’t want to define several structs,objects, or use arrays, hashtables or out parameters to accomplish something simple as this and fast (KISS - Keep it simple stupid ;)). If this is a bad design, well in that case I can leave with it. Sometimes other things than the perfect design are important. In this case to be productive ;) I’m not here to pick a fight; I only wanted to see what other think about it.

  • I also have to eschew what others have already said here: Needing multiple return values are represent an underlying design problem, especially if you need values of different types. Being a 'lazy' developer as you stated doesn't make the need warranted. It defeats the whole singleness of purpose that OO is aligned with as well. Return a collection, or a custom type instead. The overhead is minimal, and certainly not much more than if you were to allocated the multiple types directly and return them.

  • Here's a play on Fredrick's comment that doesn't require reflection:

    public static object [] GetSomething()
    {
    return new object [] { 10, 11, true };
    }

  • With proper design, you will never need to use the out parameter.

  • I thought that syntax looked strangely familiar... Then I read the last line!

    Though, in LUA, I still think a variable name is required for the "garbage" returned values, even if the same variable is reused.

    Instead of:

    var x,,,isHidden = GetCords("MyElement");

    We would need something like:

    var x, _, _, isHidden = GetCords("MyElement");

    -Jaesyn(Dalaran)

  • I think this would end up causing more work for us lazy developers in the long run. A developer would need to think pretty hard about what values would be returned by said method. Intellisense can't help because when they're typing "var x,???" it doesn't know what will be placed to the right of the "=". Also, it leaves room for a developer to accidentally mix up the order: var y,x = GetPoint().

    Maybe a cooler solution would be a refactoring in VS. rt click -> Refactor -> Anonymous Type to Class.

  • I vote ugly, I would even say fugly. To me it looks much worse than out parameters.

    As for the membership:
    CreateUser aught to return the 2 values in a single "CreationResult" type.
    I would say that given the decision to use one out param and one return value, the return value should have been the status because you always need to know the status, but often don't need the profile until the next page loads (redirectfromlogin)

  • I'm not sure what the "singleness of purpose that OO is aligned with" is. To me, OO is encapsulation, taking a bundle of behavior and separating the interface from the implementation so that the interface can be used to create more complex behavior without the added complexity of the implementation.

    Sometimes functions do have multiple things to return.

    int line, int column FindCursorPositionInText(String text, int offset);

    Adding out parameters is cramming new meaning into parameters that shouldn't be there.

    A lot of dynamic languages have no problem returning stuff like this, since they can just pile everything into an array and let the interpreter figure out the types later. Getting the function to return a typed object is possible without adding complication (see the syntax I wrote above), but you need parallel assignment to make things work in the end (if you want to preserve type safety.

    line, column = FindCursorPositionInText(text, offset);

  • Have a look at "yield return" in C#

    public class CityCollection : IEnumerable
    {
    string[] m_Cities = {"New York","Paris","London"};
    public IEnumerator GetEnumerator()
    {
    for(int i = 0; i<m_Cities.Length; i++)
    yield return m_Cities[i];
    }
    }

  • That's one of the things I really like about Python: the tuple.

    Back in August, I ported a static helper class I had in C# to IronPython. In C# I had a method like this:

    public static DateTime[] GetWeekBeginEnd(DateTime date)

    which returns the week begin and end datetimes for a given date. It's used something like this:

    DateTime[] weekBeginEnd = GetWeekBeginEnd(workingDate);
    CalendarWeekBegin.SelectedDate = weekBeginEnd[0]; // 0 = week begin
    CalendarWeekEnd.SelectedDate = weekBeginEnd[1]; // 1 = week end

    However, in IronPython my method signature looks like this:

    def GetWeekBeginEnd(self, date)

    Inside the method, my return statement simply look like this:

    return weekBegin, weekEnd

    And the usage looks like this:

    weekBegin, weekEnd = self.GetWeekBeginEnd(workingDate).




  • Singleness of purpose: A method should only do one thing. Easy concept, and is programming 101 or so I thought. If you need multiple return values, either package them into a data structure, or implement a collecting parameter and spread the values out over multiple methods. The more return values you cram into a method, the harder it will be for client code to A) figure out exactly what it needs from the method and B) it limits the amount of client code that can actually get use from the method.

    The times multiple return values are needed are few and far between, so why limit the usefulness of a method to satisfy what is more than likely an edge case?


  • About documentation: Intellisense ftw! ;)

  • Ruby supports multiple return values. It comes in handy sometimes.

    The Ruby does it is by returning an Array that contains the values, and provides some syntactic sugar to keep your code clean. For example:

    def stats
    return 'Bob', 90, 'blue'
    end

    name, age, favorite_color = stats

    Without the syntactic sugar, you'd have to parse the array manually:

    my_stats = stats
    name = my_stats[0]
    age = my_stats[1]
    favorite_color = my_stats[2]

    This is a contrived example that might feed the "this isn't OO" fire, but this technique can be convenient.

  • This sounds like a bad, bad idea.

  • Just chiming in to concur with mostly everyone else. Multiple return values? Blachh! What a disgusting mess...

  • int line, int column FindCursorPositionInText(String text, int offset);
    ...
    line, column = FindCursorPositionInText(text, offset);

    is more disgusting than

    class CursorPosition
    {
    int line;
    int column;
    };
    CursorPosition FindCursorPositionInText(String text, int offset);
    ...
    CursorPostion position = FindCursorPositionInText(text, offset);
    line = position.line;
    column = position.column;


    2 lines of code is better than 6 in my book. Neither is hard to understand, but I bet if everyone were used to the syntax we would all find the first easier in more complex situations.

    I think the best implementation in a C# compiler is to automatically generate the class for the programmer and then allow multiple assignment. Essentially, the compiler writes all that boiler plate for you.


  • If you don’t like Tuple (Multiple returns), you probably not like the idea of making it possible to return an anonymous type as a typed type. For example:
    return new { X = 10, Y = 20 };
    var point = GetCords(“MyElement”);
    point.X
    Returning anonymous type is possible but we need to use reflection to get the values. But returning anonymous type will be more difficult to maintain an understand than Tuple, just a thought ;)
    Using out-put parameters are so ugly, a method shoule only take parameters with a value, not returning the value through a parameter. The method itself should return a value, if it’s one or more doesn’t matter for me. But if Tuple was supported, we should be careful how to use it. Btw to start some other discussion, why is it allowed to pass several parameters to a method and only return one value? I mean, why should a method take more than one parameters at all if it’s not allowed to return more values? Why not pass objects, structs, arrays or haschtables every time to a method, and only allow one parameter for a method, just a thought ;)

  • I'm baffled by the arguments here regarding design ... why can't you have strongly typed return values? What is so elegant about creating another type just to return your data from a function?

    This happens in plenty of other languages -- believe me, no one gets confused. You "design" guys are wacked.

    Go Fredrik.

  • i like the idea, i'm sure you many be able to do it IL. all it is pushing the values into the stack and poping them after the method call.

  • var point = GetCords(“MyElement”);

    That seems better, assuming that there is intellisense for the inferred type.

    You could create a generic Pair triplet etc...


  • This is gonna be an awesome feature!!! I hope c# will have it! I've been thinking about it too!

  • What you seem to want is tuples, something that can be found in Haskell:

    let (x, y, _, t) = foo (3, 4)
    in bar (x, y, t)

  • It would be easy to allow multiple return values with C# without any design change:

    Preprocessing of compiler could change

    (double x, double y) = MyMethod(a, b)

    automatically to

    double x;
    doubly y;
    x = MyMethod(a, b, y);

    if MyMethod is defined as double MyMethod(a, b, double out y)

    or

    double x;
    doubly y;
    MyMethod(a, b, x, y);

    if MyMethod is defined as void MyMethod(a, b, double out x, double out y)

    Of course this should be possible without variable declaration:

    double x; // declare myself
    double y; // declare myself
    (x, y) = MyMethod(a, b)

    Preprocessor just should allow a group of (return value, out param1, out param2, ...) to be left of the assigment statement.

    For those who scare about concatenating return and out params, you could use
    "(x, out y)" or "(double x, double out y)" syntax. Please be aware that C# itself does mix up return and params when using "Func" generic type.

Comments have been disabled for this content.