【发布时间】:2022-01-14 04:48:12
【问题描述】:
我有以下实际工作的代码示例:
namespace DeviceLib
{
public interface IInstrument
{
event Action<InstrumentConnectionStatus> OnConnectionChanged;
event Action OnRemoteMeasureRequested;
}
public class InstrumentInstance
{
public delegate Task EventCompletedHandler(object sender, dynamic eventArgs);
public event EventCompletedHandler StatusChanged = async delegate { };
public event EventCompletedHandler RemoteMeasureRequested = async delegate { };
IInstrument Instrument;
public InstrumentInstance(string DriverName)
{
Instrument = DriverName switch
{
Instrument1.DRIVER => new Instrument1Driver(),
instrument2.DRIVER => new Instrument2Driver(),
_ => throw new NotSupportedException($"Driver {DriverName} not supported"),
};
}
public async Task<object> OnStatusChanged()
{
Instrument.OnConnectionChanged += async (InstrumentConnectionStatus status) =>
{
await StatusChanged(nameof(OnStatusChanged), status.ToString());
};
return null;
}
public async Task<object> OnRemoteMeasureRequested()
{
Instrument.OnRemoteMeasureRequested += async () =>
{
await RemoteMeasureRequested(nameof(OnRemoteMeasureRequested), null);
};
return null;
}
}
}
namespace DeviceConsumer
{
public class InstrumentService
{
static Type Type = typeof(DeviceLib.InstrumentInstance);
DeviceLib.InstrumentInstance InstrumentInstance;
static List<MethodInfo> AvailableEventHandlers = Type.GetMethods().Where(x => x.DeclaringType == Type && !x.IsSpecialName && x.Name.StartsWith("On")).ToList();
static List<EventInfo> AvailableEvents=Type.GetEvents().ToList();
public InstrumentService()
{
}
public async Task CreateInstrumentInstance(string driverName)
{
this.InstrumentInstance = new DeviceLib.InstrumentInstance(driverName);
// Invoking the methods that wrap the event handlers with reflection
foreach (MethodInfo eventHandler in AvailableEventHandlers)
await (Task<object>)eventHandler.Invoke(InstrumentInstance, new object[] { });
InstrumentInstance.StatusChanged += async(s,e) => await ProcessInstrumentEvent(s,e);
InstrumentInstance.RemoteMeasureRequested += async (s, e) => await ProcessInstrumentEvent(s, e);
}
private async Task ProcessInstrumentEvent(object sender, dynamic eventArgs)
{
await Task.Run(() =>
{
Console.Write($"Event {sender} Fired!");
});
}
}
现在我想替换将事件关联到 ProcessInstrumentEvent 方法的静态部分:
InstrumentInstance.StatusChanged += async(s,e) => await ProcessInstrumentEvent(s,e);
InstrumentInstance.RemoteMeasureRequested += async (s, e) => await ProcessInstrumentEvent(s, e);
类似的东西:
foreach (EventInfo ev in AvailableEvents)
{
// EventHandler handler = async delegate (object s, dynamic e) { await ProcessInstrumentEvent(s, e); };
// EventHandler handler = new EventHandler(async (s, e) => await ProcessInstrumentEvent(s,e));
ev.AddEventHandler(InstrumentInstance, handler);
}
定义“处理程序”的两种方法都不起作用,我在这里失败了吗?我认为我非常接近,此实现的目标是动态添加(然后删除)针对“InstrumentService”类中的方法“ProcessInstrumentEvent”的处理程序,因此不使用 += 和 -= 运算符,所以我认为我可以使用反射方法“AddEventHandler”和“RemoveEventHandler”来实现这一点
【问题讨论】:
-
作为旁注:
dynamic eventArgs让我觉得……不必要且令人困惑 -
它成功了,我知道错误在哪里,非常感谢! PS“动态事件参数”在此示例中是不必要的,但我在实际实现中需要它,因为其中一些事件在触发时还会携带额外的输出数据,我需要稍后在“ProcessInstrumentEvent”方法中处理这些数据
标签: c# events reflection delegates