Подтвердить что ты не робот

Отображение параметров Observable.FromEvent & CreateDelegate

Я смотрел на реализацию

Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove)

и я изо всех сил пытаюсь понять, как это работает. Позволяет сказать, что TEventHandler является стандартом:

public delegate void EventHandler(object sender, EventArgs e);

тогда меня озадачивает код:

TEventHandler d = (TEventHandler) Delegate.CreateDelegate(
    typeof (TEventHandler),
    (object) new Action<EventArgs>(observer.OnNext),
    typeof (Action<EventArgs>).GetMethod("Invoke"));

(n.b Я специализировал этот общий код на этом конкретном экземпляре примера.)

Как создается CreateDelegate делегат подписи (obj, args), связанный с методом invoke (args) для действия? Где находится объект?

Похоже, что это может быть вокруг открытого делегата по действию, и мы принуждаем 'this' быть "firstArguemnt" из CreateDelegate и разрешать прохождение args. Если так кажется грязным?

4b9b3361

Ответ 1

Позвольте сломать его:

Во-первых, декомпиляция Rx v2.0.3, по-видимому, не имеет метода Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove), и также не существует Rx v 1.1, с которым я столкнулся. Я собираюсь предположить, что вы имеете в виду ближайшее совпадение, которое я могу найти:

public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)

Глядя на декомпилированный источник для Rx 1.1 (источник 2.0 отправился на нас всем астронавтом архитектуры и полон косвенности, что делает его намного сложнее). Фактический фрагмент кода, использующий рефлектор для декомпиляции, таков:

Action<TEventArgs> o = new Action<TEventArgs>(observer.OnNext);
    TDelegate d = CreateDelegate<TDelegate>(o,
        typeof(Action<TEventArgs>).GetMethod("Invoke"));

    addHandler(d);

Итак, вопрос:

Как создается CreateDelegate делегат подписи (obj, args), связанный с методом invoke (args) для действия? Где находится объект?

Я не уверен, понял ли я совершенно правильно, но, похоже, вопрос конкретно имеет значение. Как CreateDelegate<TDelegate>(o, typeof(Action<TEventArgs>).GetMethod("Invoke") создает метод только с параметром args - что происходит с объектом o

Что происходит, да, объект o передается как object firstArgument для внутреннего .NET-метода.

public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)

Этот метод "связывает" firstArgument в основном как указатель this для возвращаемого метода. Внутри он будет хранить ссылку на firstArgument где-то внутри объекта делегата. Мы не можем видеть внутри этого, поскольку это внутренняя деталь реализации .NET и поэтому она может делать всевозможные нечетные вещи и нарушать правила там, где это угодно.

Похоже, что это может быть вокруг открытого делегата по действию, и мы принуждаем 'this' быть "firstArguemnt" из CreateDelegate и разрешать прохождение args. Если так кажется грязным?

Да, это точно то, что происходит. Это то, что предназначена для функции CreateDelegate.
Кроме того, он становится еще более грязным. CreateDelegate просто возвращает объект типа Delegate - у нас нет безопасности типа в методах args и т.д., а затем код переводит его в TDelegate - это работает, потому что делегат является особым, и вы можете отнести его на любой который имеет ту же "форму". Как и выше, это внутренняя деталь реализации .NET и поэтому может выполнять всевозможные странные вещи: -)