Отражатель - ваш друг на этом. Код, сгенерированный для второй линии выглядит примерно так (примерно):
if(Binder.IsEvent("OnMyEvent", typeof(SomeWrapperClass)))
{
Binder.InvokeMember("add_OnMyEvent", obj, myAction);
}
else
{
var e = Binder.GetMember("OnMyEvent", obj);
var ae = Binder.BinaryOperation(ExpressionType.AddAssign, e, myAction);
Binder.SetMember("OnMyEvent", obj, ae);
}
Если вы не можете использовать реальное событие для OnMyEvent
(в этом случае вы можете опереться на реализацию по умолчанию DynamicObject
), то вы» Мне нужно вернуть что-то, что реализует AddAssign
, возвращая что-то вроде делегата многоадресной передачи. Я хотел бы предложить бывший, если это возможно ...
Для удовольствия, вот хак примера, который динамически связывает OnMyEvent с OnMyOtherEvent:
public class SomeWrapperClass : DynamicObject
{
public event Action OnMyOtherEvent;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "OnMyEvent")
{
result = OnMyOtherEvent;
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (binder.Name == "OnMyEvent" && value is Action)
{
OnMyOtherEvent = (Action)value;
return true;
}
return TrySetMember(binder, value);
}
public void Test()
{
if (OnMyOtherEvent != null)
OnMyOtherEvent();
}
private static void TestEventHandling()
{
dynamic obj = new SomeWrapperClass(); // This extends DynamicObject
obj.OnMyEvent += (Action)(() => Console.WriteLine("DO something!"));
obj.Test();
}
}
Прежде всего, спасибо LOT за подсказку о том, как просто смотреть на IL, который он генерирует (ну или довольно высокоуровневое представление). Я считаю довольно интересным то, как он обрабатывает возвращаемое значение GetMember. Не могу ли я использовать статическое событие «mock» для возврата из TryGetMember для всех моих событий, а затем выполнить фактическое привязку в TryInvokeMember? (для add_XYZEvent)? – Storm 2010-11-24 17:44:48