AddEventHandler с помощью отражения

Я также использовал метод InternalsVisibleToAttribute. Стоит упомянуть также, что, если Вы чувствуете себя, неловко делая Ваши ранее закрытые методы внутренними для достижения этого, тогда возможно, они не должны быть предметом прямых модульных тестов так или иначе.

, В конце концов, Вы тестируете поведение из Вашего класса, а не это определенная реализация - можно изменить последнего, не изменяя первого, и тесты должны все еще передать.

20
задан Kjartan 1 June 2015 в 05:37
поделиться

3 ответа

Вот пример, показывающий, как прикрепить событие с помощью отражения:

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        var eventInfo = p.GetType().GetEvent("TestEvent");
        var methodInfo = p.GetType().GetMethod("TestMethod");
        Delegate handler = 
             Delegate.CreateDelegate(eventInfo.EventHandlerType, 
                                     p, 
                                     methodInfo);
        eventInfo.AddEventHandler(p, handler);

        p.Test();
    }

    public event Func<string> TestEvent;

    public string TestMethod()
    {
        return "Hello World";
    }

    public void Test()
    {
        if (TestEvent != null)
        {
            Console.WriteLine(TestEvent());
        }
    }
}
35
ответ дан 29 November 2019 в 22:50
поделиться

Вот короткий, но полный пример того, что действительно работает:

using System;
using System.Reflection;

class EventPublisher
{
    public event EventHandler TestEvent;

    public void RaiseEvent()
    {
        TestEvent(this, EventArgs.Empty);
    }
}

class Test
{

    void HandleEvent(object sender, EventArgs e)
    {
        Console.WriteLine("HandleEvent called");
    }

    static void Main()
    {
        // Find the handler method
        Test test = new Test();
        EventPublisher publisher = new EventPublisher();
        MethodInfo method = typeof(Test).GetMethod
            ("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);

        // Subscribe to the event
        EventInfo eventInfo = typeof(EventPublisher).GetEvent("TestEvent");
        Type type = eventInfo.EventHandlerType;
        Delegate handler = Delegate.CreateDelegate(type, test, method);

        // Raise the event
        eventInfo.AddEventHandler(publisher, handler);
        publisher.RaiseEvent();
    }
}

Теперь, когда вы говорите «Я только не могу запустить событие», что именно вы имеете в виду? Вы не должны сами создавать события - это должен делать издатель мероприятия. Весь ли код, который вы нам представили, работает? Если так, похоже, проблема не в добавлении обработчика событий.

Не могли бы вы предоставить дополнительную информацию?

20
ответ дан 29 November 2019 в 22:50
поделиться

Когда вы говорите, что это не работает ... что происходит? Ничего такого? Исключение?

Мысли:

  • публично ли и событие, и обработчик? Если нет, вам нужно передать подходящие BindingFlags вызовам GetEvent / GetMethod .
  • соответствует ли подпись обработчика?

Вот рабочий пример (обратите внимание, что я использую статический обработчик, отсюда нуль в Delegate.CreateDelegate ):

using System;
using System.Reflection;
class Test
{
    public event EventHandler SomeEvent;
    public void OnSomeEvent()
    {
        if (SomeEvent != null) SomeEvent(this, EventArgs.Empty);
    }
    static void Main()
    {
        Test obj = new Test();
        EventInfo evt = obj.GetType().GetEvent("SomeEvent");
        MethodInfo handler = typeof(Test)
            .GetMethod("MyHandler");
        Delegate del = Delegate.CreateDelegate(
            evt.EventHandlerType, null, handler);
        evt.AddEventHandler(obj, del);

        obj.OnSomeEvent();
    }

    public static void MyHandler(object sender, EventArgs args)
    {
        Console.WriteLine("hi");
    }
}
7
ответ дан 29 November 2019 в 22:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: