Is it theoretically possible to develop an extension method that somehow works similar to an anonymous function class?
No, because the name must be present at compile time, and the proposed extension method will rely on the Expression object to be checked at runtime.
The only way you could refer to a member by name would be if the object referenced actually has a member of that name. For the compiler, there must be an actual compile time name.
(I lie. When you use the dynamic keyword, you tell the compiler to postpone compilation operations at runtime. This allows you to avoid tricks that do not allow types with a specific member name until they are executed at runtime. This is on actually one way to achieve this goal, however, running the compiler at runtime is potentially expensive and relinquishes compilation-type security, which is a hallmark of C # and similar statically -tped The dynamic keyword is an important feature in some scenarios, but I would not say that this particular use case is worth the cost.)
Personally, I do not find the name Key problem. In one very important respect, this is very expressive: that is, he tells me that I am dealing with a grouping key. If I want to know more about this, its type is usually sufficient for further development, and it is immediately available, hovering over it.
But different strokes for different people. If the goal is to make the named member different from Key , your anonymous IMHO type projection is the best you are going to get. Note that you can improve brevity with GroupBy() overload, which allows you to project each group directly, instead of the Select() method:
var grouped_by_competition = all_events .GroupBy(e => e.Competition, (k, g) => new { Competition = k, Items = g });
So, one more thing: when I wrote that "the only way for you to be able to refer to a member by name will be if there is actually a member of that name on the object to which there is a link", there is a little manual waving there. That is, what matters is that the compiler knows about the name at compile time.
This usually means that there really is a type with a named member having that name. But there is an exception to this rule recently added in C #, which is the new tuple syntax using ValueTuple . However, you can implicitly specify a name without introducing a new new type. The compiler simply tracks it in the local method and processes it as if it were relevant.
The tuple syntax does not actually improve the syntax of the anonymous type in this particular scenario. This is a little shorter, but not much:
var grouped_by_competition = all_events .GroupBy(e => e.Competition, (k, g) => (Competition: k, Items: g));
This has the potential performance advantage of using the ValueTuple class; being a type of value, there can be a significant reduction in GC overhead by using it. But not all scenarios will benefit from this.