views:

696

answers:

3

Hi,

I do some type analysis in runtime using Reflection. If I have a MethodInfo instance, how can I figure out if this is a "real" method or is a getter/setter method of a property? And if it is a property, how can I find the its hosting PropertyInfo back?

+5  A: 

Well, the method behind a getter and setter are "real" methods.

Re tracking back to a property - the pattern (return vs take 1 arg) will help narrow it - but you'll have to call GetGetMethod/GetSetMethod on each to find the property.

You could probably try the Name (less get__/set__) - but that feels brittle. Here's the longer version (no use of Name):

static PropertyInfo GetProperty(MethodInfo method)
{
    bool takesArg = method.GetParameters().Length == 1;
    bool hasReturn = method.ReturnType != typeof(void);
    if (takesArg == hasReturn) return null;
    if (takesArg)
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
    }
    else
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
    }
}
Marc Gravell
+1 for the workaround, still prefer the 'name.StartsWith("get_" / "set_")' though.
arul
hmm... maybe for C# code, at least... they are mentioned in 17.2.7.1 of ECMA 335 - but is this applied over other languages? I'll check ECMA 334...
Marc Gravell
Sure it is, check section 17.2.7.1.For a property P of type T, the following signatures are reserved:T get_P();void set_P(T value);Both signatures are reserved, even if the property is read-only or write-only.
arul
That is just C#; 22.34 of the CLI spec says "typically" - not "exclusively". So if you are consuming C# classes: fine. Otherwise: brittle. I got the spec numbers reversed, BTW.
Marc Gravell
Actually, to be CLS compliant they must be named this way (informative text) - but it isn't guaranteed in the more general case. So I stand by my claim ;-p
Marc Gravell
+3  A: 

Look into MethodBase.IsSpecialName. Methods which shouldn't be plainly visible, such as property accessors, event subscription methods and operator overloads use this flag.

To my knowledge, there isn't a way to find the PropertyInfo without iterating through the properties and comparing the methods.

Barry Kelly
According to MS, you can't guarantee that the IsSpecialName flag will be set:http://connect.microsoft.com/VisualStudio/feedback/details/108302/for-property-accessors-get-set-isspecialname-false
Brandon Payton
IsSpecialName does appear to work though. I hope this is something MS changed because it's better to be able to check the flag rather than having to reason upon what language features are implemented as (possibly unmarked) special methods.
Brandon Payton
+2  A: 

Ecma 335 specifies (but does not demand) that compilers use the get_/set_ prefixes (chapter 22.28). I don't know any language that breaks that recommendation. Making it easy:

public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) {
  if (!method.IsSpecialName) return null;
  return t.GetProperty(method.Name.Substring(4), 
    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
}
Hans Passant
From the informative text, it is required to be CLS compliant, but not required to be valid IL.
Marc Gravell
I wouldn't recommend going this way. I recommend checking all the properties. String pattern convention - not robust.
Barry Kelly
I'd love to see a counter-example.
Hans Passant
This is a duplicate comment, but in case it is missed below...According to MS in 2005, the IsSpecialName flag is not guaranteed to be set for property get/set methods:http://connect.microsoft.com/VisualStudio/feedback/details/108302/for-property-accessors-get-set-isspecialname-false
Brandon Payton
@brandon - The assertion "it is always false" in that report is obvious nonsense.
Hans Passant