-3

I have a class which contains public static event, and I need to find out if it has handler attached to it or not. I know that I can use GetInvocationList() (if event is not static then I can find it by GetField() method) but the issue is that the event is static and I cannot seem to get a value by using reflection.

public class Business
{
  public static event EventHandler MyEvent;
}

I need to get event handlers of this event but from another class:

public class MyClass
{
  public void Test()
  {
    FieldInfo fieldInfo = typeof(Business).GetField("MyEvent", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
    // fieldInfo is null!!
    Delegate del = (Delegate)fieldInfo.GetValue(null);
    var list = del.GetInvocationList();
  }
}

I cannot get it to work to have fieldInfo returned with value instead of null!

Dark_Knight
  • 387
  • 4
  • 20
  • Typo: just use `var eventInfo = typeof(Business).GetEvent(nameof(Business.MyEvent), BindingFlags.Static | BindingFlags.Public);` –  Aug 25 '21 at 18:39
  • @OlivierRogier but how to get GetInvocationList() ? – Dark_Knight Aug 25 '21 at 18:40
  • @Dark_Knigh "*but how to get GetInvocationList()*" => That, is another question and I don't know what GetInvocationList is related to the original question, except that you mention it in the title, and what you want to do with it. Feel free to improve or correct the question or to open a new question for this. But here, it's a typo as mentionned. Thus you should now be able to advance using the good type. –  Aug 25 '21 at 18:40
  • 2
    Does this answer your question? [How to get a delegate object from an EventInfo?](https://stackoverflow.com/questions/3783267/) and [c# How to get added events?](https://stackoverflow.com/questions/12476088/) and [finding the Delegate Method registered to an Event](https://stackoverflow.com/questions/2350130/) and [Getting suitable eventHandler after GetInvocationList()](https://stackoverflow.com/questions/8512018/) and [How to get invocation list of an explicit event in C#](https://stackoverflow.com/questions/34827528/) –  Aug 25 '21 at 18:46
  • 3
    Since Business is your own class why use reflection instead of a method dedicated to get the invocation list? eg. https://dotnetfiddle.net/6hFdLi – Rand Random Aug 25 '21 at 18:54
  • @OlivierRogier, I am trying to find out if an event has already attached event handler or not because I have a generic method which attaches handlers. The main issue here is that the event is static; if it is not static then I can find it by GetField(...) – Dark_Knight Aug 25 '21 at 18:57
  • @Dark_Knigh The problem is not about being static, but to use GetEvent and not GetField because an event is not a field, as well as a field is not a method: https://stackoverflow.com/questions/10367137/. You can basically have 5 things in a class: consts, fields, properties/indexer, methods, and events (if I don't forget some... and also constructors... and inner delegates, classes, interfaces, enums...). See [Type.GetX](https://learn.microsoft.com/dotnet/api/system.type) to find all possible things. But remember that over-using reflexion can break OOP up to the roots of the Theory. –  Aug 25 '21 at 19:16
  • @OlivierRogier, I am aware of that but when I was searching I found that solutions are to use GetField to be able to GetInvocationList for the delegate. `FieldInfo fi = we.GetType().GetField(ev.Name, BindingFlags.Static | ` ` BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | ` ` BindingFlags.FlattenHierarchy);` ` Delegate del = (Delegate)fi.GetValue(we);` `var list = del.GetInvocationList();` – Dark_Knight Aug 25 '21 at 19:17
  • 1
    The auto generated delegate field is not public so `BindingFlags.Public` will not work, use `BindingFlags.NonPublic` instead. But if this meant to be a general solution, then be warned that nothing guarantees that a field with the same name is generated (it is the behavior of the current C# compiler), and does not work for events with explicit accessors anyway. – György Kőszeg Aug 25 '21 at 19:20
  • @GyörgyKőszeg, Thanks, first test seems to work :) – Dark_Knight Aug 25 '21 at 19:27
  • @RandRandom, I am ending up using your solution as the class is generic abstract and I am actually trying to get the events of children classes, so your solution seems easier. If you post it then I will mark it as a solution. – Dark_Knight Aug 25 '21 at 20:04

1 Answers1

1

Since Business is your own class using reflection seems unncessary, that is why I would suggest just doing a simple method to get the information needed.

eg.

public class Program
{
    public static void Main()
    {
        Business.MyEvent += MyFancyEventListener; 
        var xyz = Business.MyEventsInvocationList();
        foreach (var x in xyz)
            Console.WriteLine(x);
    }
    
    private static void MyFancyEventListener(object sender, EventArgs args)
    {
        
    }
}

public class Business
{
    public static event EventHandler MyEvent;

    //add this method to your class
    public static IEnumerable<Delegate> MyEventsInvocationList() => MyEvent.GetInvocationList();
}
Rand Random
  • 7,300
  • 10
  • 40
  • 88