The Future of C# and multiple results. Why don’t we use anonymous types?

I just watched The Future of C# talk by Mads Torgersen recorded at NDC London conference over a month ago. Among all the stuff Mads talked about one really drawn my attention: methods/properties with multiple results. Unfortunately, instead of providing some new, crazy idea how to make it possible in C# he focused on making current usage easier. I think language designers could go much further and create real multiple results experience!

Mads showed couple ways to workaround lack of multiple results functionality in C#. To make it easy consider following class:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

Now, we need to extend the Point class with additional functionality: GetCoordinates() method which returns both X and Y.

How could it be done using C# we know now? There are couple ways:

  1. Using Tuple class
    public Tuple<int, int> GetCoordinates()
    {
        return Tuple.Create(X, Y);
    }

    Looks nice, but has disadvantages. The main one: you don’t get meaningful names for X and Y anymore. They are Item1 and Item2 now.

  2. Additional custom class
    Another common way to solve that issue is to make another, transportation class which does not have any other meaning at all. It’s only responsible for transporting values between methods:

    public class Coordinates
    {
        // (...)
    }
    public Coordinates GetCoordinates()
    {
        return new Coordinates(X, Y);
    }

    Why isn’t it really happy path? You have to create and maintain separate class which actually does anything but behaves as value container.

  3. out parameters
    This one is used by BCL quite often, e.g. for all TryParse methods on primitive types.

    public void GetCoordinates(out int x, out int y)
    {
        x = X;
        y = X;
    }

    Even if the method itself looks nice and clear calling that kind of method is not that simple and clean. You have to declare all variables before calling the method:

    int x, y;
    point.GetCoordinates(out x, out y);

    You also cannot use var to make these variables implicitly types, because they are not initialized when declared. Consider how painful would it be, if it was IDictionary<string, IEnumerable<Tuple<int, double, Stream, MyGenericClass<foo>>>> instead of int :)

The feature Mads describe is all about 3rd option. What if C# would allow you to declare the variable within the method call? Something like

point.GetCoordinates(out var x, out var y);

I have to say that: it looks really useful! But I think we can do more! Instead of fixing out parameters why don’t we introduce real multiple results syntax to C#? The easiest way to do that would be using anonymous types. I dream about something like

public { int X, int Y } Coordinates()
{
    return new { X, Y }
}

It have many advantages. You got tuple-like solution, with meaningful property names, implicit typing when calling the method and no pain with out stuff. And it really should not be hard to implement! Why? Because it does not require CLR support and because we already have anonymous types, and what even more important their implementation is shared within assembly as long as number of parameters, their types and names match. That’s why you can do something like that:

var x = new { Title = "myX", Value = 10 };
var y = new { Title = "myY", Value = -10 };

var array = new[] { x, y };

Both x and y are really instances of the same anonymous class, and that’s why you’re able to create an array of that type! The only thing that would be required is to make these types public instead of internal. But even as public they could (and maybe even should) be hidden from developers using e.g. special attribute.

I know that’s only my wishful thinking, but I hope someday syntax like the one described above will come true. I really look forward to project Roslyn being released as default C# compiler, because introducing that kind of features will be much easier, cheaper and because of that more likely to happen.

Share Button

11 thoughts on “The Future of C# and multiple results. Why don’t we use anonymous types?

  1. I’d use 3th option, with some syntactic sugar, eg.:

    int MyMethod(int a, out string b, out MyType c){ ... }

    and we can call this method:

    (int returnValue, string b, MyType c) = MyMethod(5);
    or:
    (r,b,c) = MyMethod(5)
    and if we’re running this method in this way variables are initialized automatically.
    This solution is still backward compatible.

    1. I like the idea, but I don’t like the fact that you can’t easily pass the results further. With anonymous types you could easily use LINQ to e.g. get list of coordinates from list of points, filter it, apply some sort order and then project to another type or aggregate.

  2. Yep, I’m getting sick of creating “result” entities that will be used once only. And since people using hacks to make it possible it’s better idea to standarise it :P

  3. To use my solution with LINQ we need to go deeper and let C# to pack and unpack tuples (not actual class) automatically like in Python. I can imagine that tuple can be easily converted to anonymous type (you have types and names) an then it could be sorted, filtered and aggregated.

    Wishful thinking :)

      1. Tuple packing/unpacking is how F# handles this. I’d actually argue that it’s a much more useful feature overall (especially if you introduce pattern matching), and probably simpler to implement than anonymous types. Returning anonymous types gets challenging when you cross assembly boundaries (ie: what do you use when this is a public facing API), especially since it’d break other languages. Working with a Tuple could make the API usable anywhere.

  4. Returning anonymous object is impossible due to static type (and will never be). When you use anonymous objects C# creates new type and gives it some name under the hood. That is the reason that you can create two anonymous objects within array. It works quite differently than in the dynamic languages (python, smalltalk). IMHO this will make code less readable and will be dangerous tool in programmers hands. You got interfaces for hiding abstraction. {int x, int y} is not really meaningfull and violates some OO principles. Unfortunately C# does not allow anonymous implementations (you can do that in JAVA)

    public T Coordinates() where T:IPointable
    {
    return new Something(x, y);
    }

    private class Something : IPointable
    {
    public X { get; private set; }
    public Y { get; private set; }

    public Something(int x, int y)
    {
    this.X = x;
    this.Y = y;
    }
    }

    IMHO that is the best way you should do this. You can also try Python :)

    regards

    1. I know compiler creates a class under the hoods to support anonymous type. Actually that’s a good thing. I don’t see how that makes anything impossible.

      With {int x, int y} compiler should still create a class and name it (you have both property name and type, you need nothing more to create a class). And when method result would be assigned to variable it would be statically typed to that particular anonymous class (you can do that using var, you don’t have to know the name compiler choose to use with anonymous type).

      And because there is only one class created for matching set of properties (matching in both name and type) you’d be sure that anonymous type you return can be easily set to a variable and used later in different methods, to create a collection or perform LINQ query.

  5. This seems like a good idea, but would it work across assemblies? I think anonymous types are compiled into the assembly in which they are used, which means that if you used equivalent anonymous types in two or more assemblies, there would actually be two or more compiled classes in the MSIL (one in each assembly). Those classes would not be interchangeable (currently), so you couldn’t return such an anonymous type from a public method, which could be invoked from another assembly. You could return them only from internal methods.

    I like the blog, by the way. :)

    1. You’re totally right. Right now classes created by compiler to match anonymous types are marked as internal. So c# team could either make them public, or limit that kind of anonymous types usage to private/internal methods too, what sounds like more appropriate way to go. If the result you’re trying to return can be used from outside your assembly it’s important enough to make separate class to handle it.

  6. Hello Marcin.
    The proposal is interesting, but…is it worthwhile? I mean that there are relatively few occasions where a similar feature would be useful, at least IMHO.
    Please, bear in mind that “out” and “ref” are forbidden in the Await/Async pattern. How would be solved that pattern in your case? At that point, you should “anonymize” the generic parameter as well! Something like:
    public async Task Coordinates()
    {
    return await new { X, Y }
    }

    Personally, I’d love seeing a feature like the F#’s ability to carry out a “partial-function” out of a function. That would be awesome!
    Congrats for the job and good luck!

Comments are closed.