dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.02k stars 4.03k forks source link

Make it easy to obtain the MethodInfo for a method #31427

Closed WillSullivan closed 5 years ago

WillSullivan commented 5 years ago

I'm knee deep in Expression land (the mascots are obscure, for some reason) and I'm finding I have to get quite a few MethodInfos for a lot of Expression.Calls, and there is just not any easy way to obtain them for complex and generic methods.

Who doesn't love reflecting over hoary old chestnuts like

method = typeof(AppDomain).GetMethod(
     nameof(AppDomain.CreateDomain), 
     BindingFlags.Public | BindingFlags.Static, 
     null, 
     new[] { typeof(string), typeof(Evidence), typeof(AppDomainSetup), typeof(PermissionSet), typeof(StrongName[]) }, 
     null);

And this doesn't look like a dirty filthy hack at all (and courtesy of Jon Skeet, no less)

method = typeof(Enumerable).GetMethods()
    .Where(m => m.Name == nameof(Enumerable.Contains))
    .Single(m => m.GetParameters().Length == 2)
    .MakeGenericMethod(typeof(int));

You have to admit this is pretty awful. Could we have a new operator to make this a little better?

Proposal: Add a methodof operator

Like typeof, which retrieves the Type of a class definition, add a methodof expression that gives us the MethodInfo for a given method. Using the above as examples, doesn't

methodof(AppDomain.CreateDomain(string, Evidence, AppDomainSetup, PermissionSet, StrongName[]))

and

methodof(Enumerable.Contains(IEnumerable<int>, int)

look almost... nay, absolutely professional? Easier to combine into a single line?

Pros

omg look at what it's replacing. And it would be possible to get intellisense involved, which GetMethod does not provide. And this means you'll know before compile time if you're doing it wrong. With GetMethod I sometimes have to bust out a prototype to play with different BindingFlags until I get something other than null back from the stupid call.

Cons

Somebody's got to code it. Although I can't think of an example I'd bet it might be possible to find a situation where the compiler isn't able to correctly identify the method you want. But if so there's always the fallback option.

I did scan the backlog for similar feature requests, but no luck. Hope I'm not wasting your time on something that's already been proposed.

sharwell commented 5 years ago

Duplicate of dotnet/csharplang#712

WillSullivan commented 5 years ago

Aaah, chose the wrong name. Thanks! I'll track that FR.