Why Is There Not a 'Fieldof' or 'Methodof' Operator in C#

Why is there not a `fieldof` or `methodof` operator in C#?

Eric Lippert (on the C# design team) has an excellent overview/discussion on this topic here. To quote:

It’s an awesome feature that pretty much everyone involved in the design process wishes we could do, but there are good practical reasons why we choose not to. If there comes a day when designing it and implementing it is the best way we could spend our limited budget, we’ll do it. Until then, use Reflection.

Why not a memberinfo() reflection function for C#

Eric Lippert talks about this extensively on his blog

To quote directly from that post:

Just off the top of my head, here are a few {reasons why this hasn't been done}. (1) How do you unambiguously specify that you want a method info of an specific explicit interface implementation? (2) What if overload resolution would have skipped a particular method because it is not accessible? It is legal to get method infos of methods that are not accessible; metadata is always public even if it describes private details. Should we make it impossible to get private metadata, making the feature weak, or should we make it possible, and make infoof use a subtly different overload resolution algorithm than the rest of C#? (3) How do you specify that you want the info of, say, an indexer setter, or a property getter, or an event handler adder?

what is fieldof() method in c#

In MSIL, the intermediate language that C# code (and a bunch of other languages) are compiled into, there is this handy fieldof operator that gets the FieldInfo of fields. However, fieldof doesn't exist in C#.

In C#, you'd need to do something like:

var type = typeof(EnclosingClass); // "EnclosingClass" is the class this code is in
// assuming PrivateImplementationDetails is private
var fieldInfo = type.GetField("PrivateImplementationDetails", BindingFlags.NonPublic);
RuntimeHelpers.InitializeArray(array, fieldInfo.FieldHandle);

How to get the methodname from a known method?

One approach is you can wrap it into delegate Action, then you can access the name of method:

string name = new Action(otherMethod).Method.Name;

Lambda expression not returning expected MemberInfo

Take the type of the expression's (first) parameter, and say

Expression<Func<C, string>> c = x => x.B; 
Type paramType = c.Parameters[0].Type; // first parameter of expression
var d = paramType.GetMember((c.Body as MemberExpression).Member.Name)[0];

How to get the methodname from a known method?

One approach is you can wrap it into delegate Action, then you can access the name of method:

string name = new Action(otherMethod).Method.Name;

C# '|' operator and arguments

Yes, | is the (bitwise) OR operator in C#. In PowerShell, however, | is the "pipe" operator to connect the output of one cmdlet to the input of another. The binary OR operator in PowerShell is -bor.

Also see about_Operators.

Property-of aka infoof -- via Rosyln?

You can easily use Roslyn to rewrite one valid C# code into another valid C# code. But it's not meant for adding extensions to the language.

Roslyn does parse invalid code too (it has to, if you want to use it for IntelliSense on an incomplete line), but since it's invalid, there is no guarantee it will do it correctly (because it's not clear what exactly does “correctly” mean). Also, I think the structure that it will use for infoof won't be very convenient for you.

To summarize: this is not what Roslyn is meant to be used for and doing it is probably a bad idea. But I think it's not impossible to do this using Roslyn.

Retrieving the name of the invoked method executed in a Func

Look Ma! No expression trees!

Here's a quick, dirty and implementation-specific version that grabs the metadata token from the IL stream of the underlying lambda and resolves it.

private static string ExtractMethodName(Func<MyObject, object> func)
{
var il = func.Method.GetMethodBody().GetILAsByteArray();

// first byte is ldarg.0
// second byte is callvirt
// next four bytes are the MethodDef token
var mdToken = (il[5] << 24) | (il[4] << 16) | (il[3] << 8) | il[2];
var innerMethod = func.Method.Module.ResolveMethod(mdToken);

// Check to see if this is a property getter and grab property if it is...
if (innerMethod.IsSpecialName && innerMethod.Name.StartsWith("get_"))
{
var prop = (from p in innerMethod.DeclaringType.GetProperties()
where p.GetGetMethod() == innerMethod
select p).FirstOrDefault();
if (prop != null)
return prop.Name;
}

return innerMethod.Name;
}


Related Topics



Leave a reply



Submit