Question

Consider this:

var me = new { FirstName = "John", LastName = "Smith" };

This is fine as we can then do this:

Console.WriteLine("{0} {1}", me.FirstName, me.LastName);

However we can't do this:

public T GetMe()
{
    return new { FirstName = "John", LastName = "Smith" };
}

because we don't know the type of T.

We could do this:

public object GetMe()
{
    return new { FirstName = "John", LastName = "Smith" };
}

but then we'd have to inspect the properties of the object using reflection in order to access them:

var p = new Prog();
object o = p.GetMe();
Type t = o.GetType();
foreach (var prop in t.GetProperties())
{
    Console.WriteLine(prop.Name + ": " + prop.GetValue(o, null));
}

However what about if we could name an anonymous type as we define it? Of course it would no longer be anonymous, however it would be more succinct and maintainable than a normal class definition.

Consider this:

public Person GetMe()
{
    return new public class Person { FirstName = "John", LastName = "Smith" };
}

The benefit being it would then be possible to return the result of a complicated Linq query from a method without having to define the class explicitly.

Consider this relatively complex Linq query:

List<int> list = new List<int>();
var query = from number in list
            select
                new
                    {
                        Number = number,
                        Square = number*number,
                        Absolute = Math.Abs(number),
                        Range = Enumerable.Range(0, number)
                    };

Instead of defining a class like so:

public class MyNumbers
{
    public int Number { get; set; }
    public int Square { get; set; }
    public int Absolute { get; set; }
    public IEnumerable<int> Range { get; set; }
}

in order to return the query variable from a method we could instead just do this:

List<int> list = new List<int>();
return from number in list
            select new public class MyNumbers
                    {
                        Number = number,
                        Square = number*number,
                        Absolute = Math.Abs(number),
                        Range = Enumerable.Range(0, number)
                    };
Was it helpful?

Solution

Actually, there's a "hack" that you can do to get an anonymous type back from a method. Consider this:

public object MyMethod()
    {
        var myNewObject = new
        {
            stringProperty = "Hello, World!",
            intProperty = 1337,
            boolProperty = false
        };

        return myNewObject;
    }

    public T Cast<T>(object obj, T type)
    {
        return (T)obj;
    }

You can now do this:

var obj = MyMethod();
var myNewObj = Cast(obj, new { stringProperty = "", intProperty = 0, boolProperty = false });

The myNewObj will now be an object of the same Type as the anonymous type.

OTHER TIPS

The language feature you need is:

public var GetMe()
{
    return new { FirstName = "John", LastName = "Smith" };
}

That is, var would be valid as a method return type, and the compiler would infer the actual type from whatever is returned. You would then have to do this at the call site:

var me = GetMe();

Any two anonymous types with members of the same type would be the same type, so if you wrote other functions returning the same pattern, they would have the same type. For any types A and B where B has a subset of the members of A, then A is assignment-compatible with B (B is like a base class of A). If you wrote:

public var GetMeFrom(var names)
{
    return new { FirstName = names["First"], LastName = names["Last"] };
}

The compiler would effectively define this as a generic method with two type parameters, T1 being the type of names and T2 being the type returned by the indexer on T1 that accepts a string. T1 would be constrained so that it must have an indexer that accepts a string. And at the call site you would just pass anything that had an indexer that accepted a string and returned any type you like, and that would determine the type of FirstName and LastName in the type returned by GetMeFrom.

So type inference would figure all this out for you, automatically capturing whatever type constraints are discoverable from the code.

IMHO the root problem is nothing to do with anonymous types, but that declaring a class is too verbose.

Option 1:

If you could declare a class like this:

public class MyClass
{ properties={ int Number, int Square, int Absolute, IEnumerable<int> Range } }

or some other similarly quick way (like the tuple example) then you wouldn't feel the need to do hacky things with anonymous types just to save some code.

When 'compiler as a service' arrives in C#5, hopefully they'll do a good job of integrating it and we'll be able to use metaprogramming to solve these kinds of problems cleanly. Party like it's 1958!

Option 2:

Alternatively, in C#4, you could just pass an anonymous type around as dynamic and avoid all the casting. Of course this opens you up to runtime errors if you rename a variable, etc.

Option 3:

If C# would implement generics in the same way as C++, then you could pass the anonymous type into a method, and so long as it had the right members, it would just compile. You'd get all the benefits of static type safety, and none of the downsides. Every time I have to type where T : ISomething in C# I get annoyed that they didn't do this!

What you are describing (named anonymous types) are basically "tuple types".

I think they would be a nice addition to C#.

If I were designing such a feature for C#, I would expose it using syntax like this:

tuple<int x, int y>

so that you could do:

public tuple<int x, int y> GetStuff()
{
}

I would then change the definition of anonymous types, so that:

new { x = 2, y = 2}

had tuple<int x, int y> as it's type, rather than an anonymous type.

Getting this to work with the current CLR is a little tricky, because once you can name an anonymous type in public signatures you need to be able to unify them across separately compiled assemblies. It can be accomplished by embedding a "module constructor" inside any assembly that uses a tuple type. See this post for an example.

The only downside to that approach is that it doesn't respect the CLR's "lazy" model for type generation. That means that assemblies that use many distinct tuple types might experience slightly slower load types. A better approach would be to add support for tuple types directly to the CLR.

But, apart from changing the CLR, I think the module constructor approach is the best way of doing something like this.

I would love this feature, there have been many times I've wanted this.

A good example is processing XML. You parse them get back an object, but then you need to make a concrete version of the object to send back to a caller. Many times you get XML that changes quite considerably and requires you make many classes to handle it. Wouldn't it be wonderful if you could just build the object using LinqToXml as a var, then just return that?

I think this would be a nice compiler magic for tuples:

Creating a tuple:

(int, string, Person) tuple = (8, "hello", new Person());

equivalent to:

Tuple<int,string,Person> tuple = new Tuple<int,string,Person>(8 ,"hello", new Person());

In a function:

public (int, string, Person) GetTuple(){
    return ...
}

Getting values:

int number = tuple[1];
string text = tuple[2];
Person person = tuple[3];

Could you create an Interface with the properties FirstName and LastName and use that?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top