Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to tell if a method is an event or property accessor?

Tags:

c#

reflection

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?

like image 753
AlphaModder Avatar asked Sep 14 '25 10:09

AlphaModder


2 Answers

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:

enter image description here

like image 128
Lasse V. Karlsen Avatar answered Sep 16 '25 01:09

Lasse V. Karlsen


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);
      }

    }
  }

}

}

like image 32
Radin Gospodinov Avatar answered Sep 16 '25 01:09

Radin Gospodinov