That is, how can I, given a MethodInfo
check if a method is the getter or setter of a property or the adder or remover or firer (?) of an event, without enumerating all the Property/EventInfos
in the containing type. Does the compiler mark these methods with some information that would allow me to know when my MethodInfo
is one?

- 3,266
- 2
- 28
- 44
-
What do you mean a method is an event? Do you mean an "Add" or "Remove" event methods? – Yacoub Massad Dec 29 '15 at 00:04
-
1for properties check this question: http://stackoverflow.com/questions/16718772/is-the-method-naming-for-property-getters-setters-standardized-in-il – Yacoub Massad Dec 29 '15 at 00:06
-
1Only whether it is an event/property, or the property attached to it? Or that property/event. My first guess is that you cannot. Furthermore can you please make your question a bit more *canned*? Now one has to look to the title. – Willem Van Onsem Dec 29 '15 at 00:09
-
@Yacoub Massad Yeah. I believe those are also called accessors. Title is meant to be (event or property) accessor, rather than (event or (property accessor)). – AlphaModder Dec 29 '15 at 03:37
-
@WillemVanOnsem I don't need to know the property, no. I just need to know if the method is one at all. I've edited the question to contain more in the body. – AlphaModder Dec 29 '15 at 03:39
-
1How reliable does this need to be? Unless you go over all properties and events, it is unavoidable that you will get it wrong for some methods of some assemblies. But if for instance such assemblies are never produced by the C# compiler, you might not care. – Dec 29 '15 at 07:09
3 Answers
This is not a complete solution but on the condition that the property type is not EventHandler, you can tell property get/set methods from event add/remove methods by checking their parameters and return values.
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
foreach (var methodInfo in typeof(TestClass).GetMethods())
{
if (!methodInfo.IsSpecialName)
continue;
CheckMethod(methodInfo);
}
// Method get_Name -> Property Get
// Method set_Name -> Property Set
// Method add_NameChanged -> Event Add/Remove
// Method remove_NameChanged -> Event Add/Remove
}
static void CheckMethod(MethodInfo info)
{
var parameter = info.GetParameters().FirstOrDefault();
if (parameter != null)
{
if (parameter.ParameterType.BaseType == typeof(MulticastDelegate))
{
Trace.WriteLine($"Method {info.Name} -> Event Add/Remove");
}
else
{
Trace.WriteLine($"Method {info.Name} -> Property Set");
}
}
else if (info.ReturnType != typeof(void))
{
Trace.WriteLine($"Method {info.Name} -> Property Get");
}
}
}
public class TestClass
{
public string Name
{
get { return _name; }
set
{
if (_name == value)
return;
_name = value;
NameChanged?.Invoke(this, value);
}
}
private string _name;
public event EventHandler<string> NameChanged;
}

- 2,764
- 1
- 13
- 24
-
IsSpecialName was the one I was looking for, definitely eliminates set_name, get_name methods – DanielV Jan 20 '22 at 10:30
At least one difference between a manually declared method and one that was generated by the compiler is the presence of a SpecialName
attribute in its MethodInfo
object:
To find out which property the method is linked to you would inspect PropertyInfo
objects to find their corresponding GetMethod
and SetMethod
properties, which would link to those methods.
Example LINQPad program:
void Main()
{
typeof(Test).GetProperties().Select(property => new { property.MetadataToken, property.Name, getter = property.GetMethod?.MetadataToken, setter = property.SetMethod?.MetadataToken }).Dump();
typeof(Test).GetMethods().Select(method => new { method.MetadataToken, method.Name, IsSpecial = (method.Attributes & MethodAttributes.SpecialName) != 0 }).Dump();
}
public class Test
{
public int Value
{
get;
set;
}
}
Output:

- 380,855
- 102
- 628
- 825
MethodInfo.IsSpecialName is set to true for properties and events accessors, also for some other special methods as operators overload and etc. So you can check this flag along with checking the parameter type. The following test program will output the event add/remove accessors:
public class MyEventClass {
private event EventHandler test;
public event EventHandler TestEven {
add { test += value; }
remove { test -= value; }
}
}
class Program { static void Main(string[] args) {
Type myTestClassType = typeof (MyEventClass);
var methods = myTestClassType.GetMethods();
foreach (var methodInfo in methods)
{
if (methodInfo.IsSpecialName)
{
var parameters = methodInfo.GetParameters();
if (parameters.Count() == 1 && parameters.ElementAt(0).ParameterType == typeof (EventHandler) &&
(methodInfo.Name.Contains("add") || methodInfo.Name.Contains("remove")))
{
Console.WriteLine(methodInfo.Name);
}
}
}
}
}

- 2,313
- 13
- 14