Champion: using aliases for any types (VS 17.6, .NET 8) · dotnet/csharplang · Discussion #8644 (original) (raw)

@CyrusNajmabadi Anonymous types have no user expressible name/syntax that you can use to refer to their type.

...which is kinda silly now in 2022: It's a shame that Anonymous Types were originally C# 2.0 to simplify code and allow C# users to be more expressive without the ceremony of fleshed-out class type definitions, but because the design of ATs (and their atrocious ergonomics) seemingly haven't been touched since 2005 it means that any time-savings of using ATs are eliminated by the fact you need to revert back to using ceremonious class definitions if you want to do anything useful with ATs:

I do understand why there were these restrictions back in C# 2.0: insufficient dev-time budget for release-day improvements, "less is more", and wanting to see how C# programmers would end-up using anonymous-types to see if further investment in improvements is worthwhile.

While it's now clear that C# 4.0's:Tuple<>, and C# 7.0's ValueTuple<> and C# 9.0's record class types are all simply better at being low-ceremony types compared to ATs, unfortunately there's plenty of showstoppers:

I made a quick comparison table of the main different kinds of product-type/record/tuple in C# today, which I think demonstrates the gap that ATs fall into:

C# Version Definition tedium Has "real" named properties EF/Core Linq projection Exportable Implement interface Custom ctors and class invariants
Mutable class 1.0 Medium Yes Yes Yes Yes Yes, but not with EF: must use mutable properties in projections.
Immutable class 1.0 High Yes Not supported Yes Yes Yes, but not supported by EF at all.
Anonymous Type 2.0 Low Yes Yes No No No
System.Tuple<> 4.0 Low No Not supported Yes No No
System.ValueTuple<> 7.0 Low No. Member names set with attributes. Unsafe. Not supported Yes No No
record class 8.0 Low Yes, but no camelCasing of param names Not supported Yes Yes Yes, but this is surprisingly difficult, and often requires long-form ctor definitions, which eliminates one of record types' main ergonomic advantages: terseness.

So looking at the table above, every product-type-kind in C# has its own deal-killers: some of which are unavoidable (e.g. the lack of safety with ValueTuple if you get careless with member names), but some current deal-killers, as listed above, certainly (in my opinion) can and should be rectified somehow - so without getting too side-tracked from this thread's original topic of using aliases, I'd like to suggest: