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?
6 Answers
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();
}
}

- 1,026,079
- 266
- 2,566
- 2,900
-
+1 for the workaround, still prefer the 'name.StartsWith("get_" / "set_")' though. – arul Feb 06 '09 at 13:09
-
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 Feb 06 '09 at 13:13
-
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 Feb 06 '09 at 13:15
-
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 Feb 06 '09 at 13:22
-
1Actually, 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 Feb 06 '09 at 13:24
-
1Also see the answer from Groostav. The above code assumes that a setter (`set` accessor) has exactly one parameter, but to the framework, indexers (which have arguments inside a square bracket `[]` in C# notation) are also a kind of properties, and both their getters and setters have more arguments. So it might be interesting to change the above method, to have it work with indexer accessors as well. – Jeppe Stig Nielsen Mar 11 '13 at 09:44
-
In some scenarios you may want consider using `method.ReflectedType` instead of `method.DeclaringType`. – Manfred Mar 09 '17 at 19:19
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);
}

- 922,412
- 146
- 1,693
- 2,536
-
2From the informative text, it is required to be CLS compliant, but not required to be valid IL. – Marc Gravell Feb 06 '09 at 13:25
-
2I wouldn't recommend going this way. I recommend checking all the properties. String pattern convention - not robust. – Barry Kelly Feb 06 '09 at 17:27
-
1
-
1This 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 Feb 21 '10 at 01:14
-
@brandon - The assertion "it is always false" in that report is obvious nonsense. – Hans Passant Feb 21 '10 at 08:10
-
4@HansPassant: Counter-example: when MethodInfo is the getter/setter for a property that is a C# explicit property implementation, the getter and setter methods and property names will be prefixed with the full type. That is, `object IInterface.Prop { get { return null; } }` will, in a simple case (I do not know what happens when a property with the same name already exists), be materialized by a private `IInterface.get_Prop` method and a private `IInterface.Prop` property. – Jean Hominal Jun 17 '13 at 13:01
I'd really like to leave this as a comment, but I cant since my rep isnt high enough :(
Theres a bug in Marc Gravell's code: if its an indexer it will return null, even when a parent property exists. Its nice to have that quick-fail, but I think we can only do so when it has neither a return value or a parameter:
[Pure]
public static PropertyInfo GetParentProperty(this MethodInfo method)
{
if (method == null) throw new ArgumentNullException("method");
var takesArg = method.GetParameters().Length == 1;
var hasReturn = method.ReturnType != typeof(void);
if (!(takesArg || hasReturn)) return null;
if (takesArg && !hasReturn)
{
return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method);
}
else
{
return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method);
}
}

- 3,170
- 1
- 23
- 27
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.

- 41,404
- 5
- 117
- 189
-
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 Feb 21 '10 at 01:13
-
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 Feb 21 '10 at 01:23
For present day .NET, I believe the following is equivalent to Marc's answer but more concise and maybe a slight bit more efficient. I may have missed something.
public static PropertyInfo? GetPropertyInfo(this MethodInfo getSetMethodInfo)
=> getSetMethodInfo.DeclaringType?.GetProperties()
.FirstOrDefault(prop => prop.GetSetMethod() == getSetMethodInfo
|| prop.GetGetMethod() == getSetMethodInfo);

- 34,009
- 10
- 83
- 174
The trick to play with is BindingFlags.DeclaredOnly and IsSpecialName

- 25,766
- 43
- 127
- 173