This project is read-only.

Anonymous types & generics

Topics: C# Language Design
Apr 11, 2014 at 7:15 PM
My rash reply to the suggestion to [make anonymous objects implement IReadOnlyDictionary<string,object>]https://roslyn.codeplex.com/discussions/541873) actually pointed out that current anonymous type implementations require generics, i.e.:
var anon = new { A = "s", B = 5, C = false, D = 'c' };
turns (roughly) into
class AnonymousType<TA, TB, TC, TD>
{
    public TA A { get; }
    public TB B { get; }
    public TC C { get; }
    public TD D { get; }
}
and
new AnonymousType<string, int, bool, char>("s", 5, false, 'c')
at call site.

Now can anybody explain to me what advantages has this over strongly typed class, like
class AnonymousTypeStringInt32BoolChar
{
    public string TA { get; }
    public int TB { get; }
    public bool TC { get; }
    public char TD { get; }
}
? The re-use ability is quite limited, given you would need the members to have the same name.

So is it due to the performance of equality testing that would require object.Equals otherwise? Or is there other fundamental issue I don't see?

It would be cool if we could use anonymous types without generics (i.e. on .NET Micro Framework), especially when LINQ works without them.

Thanks!
Apr 11, 2014 at 8:44 PM
Or is there other fundamental issue I don't see?
The specification doesn't say that the anonymous type is supposed to be generic, in fact it shows a non generic class in an example.

I suspect that it's done like this for the sake of reuse (as limited as it might be), minimizing the number of types is always a good thing. It's also simpler to implement, for generics the "AnonymousTypeKey" that's used to find already generated types contains only property names. If you don't use generics then you need the property types too.

I'm not sure what object.Equals has to do with this, one way or another the Equals/GetHashCode have to be generated.
Apr 11, 2014 at 8:51 PM
I'm not sure what object.Equals has to do with this, one way or another the Equals/GetHashCode have to be generated.
The reason I have mentioned this is because the comparison on anonymous classes (the Equals and GetHashCode method implementation) is using EqualityComparer<TX>.Default for the individual properties. I can imagine this is actually faster than using object.Equals.
Apr 11, 2014 at 9:00 PM
That doesn't mean that the anonymous type itself has to be generic:
return EqualityComparer<string>.Default.Equals(TA, other.TA) && EqualityComparer<int>.Default.Equals(TB, other.TB) && ...
In fact, for certain well known types this could simply be:
TA == other.TA && TB == other.TB ...
Apr 11, 2014 at 10:18 PM
Edited Apr 11, 2014 at 10:18 PM
That doesn't mean that the anonymous type itself has to be generic:
That's true but it doesn't really help not having generic anonymous types when generics are still required elsewhere. So the current implementation uses generics for two things. I don't call for changing the implementation, I just wanted to trigger thoughts whether there might be an acceptable way to enable this scenario. However, there probably isn't, unless there was a switch or something on the compiler to hint that generics are not going to happen.
Apr 12, 2014 at 5:53 PM
Eric Lippert has an article explaining that.

Basically, it's to make that anonymous types that contain protected types work, while also ensuring that there aren't two generated anonymous types that are the same (within a single assembly).
Marked as answer by JanKucera on 4/12/2014 at 2:48 PM
Apr 12, 2014 at 10:53 PM
Here we go, thanks for reminding that one. All the other stuff working without generics actually suggests there is an important reason for such requirement.