让我们假设我们有MissionA,MissionB,并且我们希望在任何任务开始时进行广播。如何在C#中实现?
类似于以下内容(它们分别位于不同的.cs文件中):
总干事(在MissionGeneral.cs中):
namespace MissionGeneral
{
public class MissionGeneral
{
public delegate void MissionStartedEvent(string name);
public event MissionStartedEvent OnMissionStart;
}
}
子任务A(在MissionA.cs中):
namespace MissionA
{
public class MissionA
{
public delegate void MissionStartedEvent(string name);
public event MissionStartedEvent OnMissionStart;
protected virtual void HandleMissionStartedEvent()
{
OnMissionStart?.Invoke("MissionA");
}
}
}
子任务B(在MissionB.cs中):
namespace MissionB
{
public class MissionB
{
public delegate void MissionStartedEvent(string name);
public event MissionStartedEvent OnMissionStart;
protected virtual void HandleMissionStartedEvent()
{
OnMissionStart?.Invoke("MissionB");
}
}
}
Broadcaster(在Broadcaster.cs中):
using MissionGeneral;
namespace Broadcaster
{
public class Broadcaster
{
public MissionGeneral mission = new MissionGeneral();
public Broadcaster()
{
mission.OnMissionStart += (_name) =>
{
Console.WriteLine($"This is {_name}");
if (_name == "MissionA") Console.WriteLine("Additional MissionA info");
else if (_name == "MissionB") Console.WriteLine("Additional MissionB info");
};
}
}
}
答案 0 :(得分:0)
执行此操作的方法是:
将触发事件的对象传递给事件
public delegate void MissionStartedEvent(MissionGeneral sender);
public event MissionStartedEvent OnMissionStart;
让对象本身向处理程序提供所需的信息:
public Broadcaster()
{
mission.OnMissionStart += (sender) =>
{
Console.WriteLine($"This is {sender.Name}");
Console.WriteLine($"Additional info: {sender.AdditionalInfo}");
};
}
如果MissionGeneral
的每个子类型必须具有Name
,AdditionalInfo
或其他的特定实现,则在基类中创建这些方法virtual
并在必要时覆盖它们
如果需要在事件处理程序中访问特定于子类型的成员,则可以始终进行模式匹配(这不是很好的方案,但是比基于字符串识别类型要好得多):
mission.OnMissionStart += (sender) =>
{
Console.WriteLine($"This is {sender.Name}");
switch (sender) {
case MissionA a:
Console.WriteLine(a.SomeSpecificMissionAMember);
break;
case MissionB b:
Console.WriteLine(b.SomeSpecificMissionAMember);
break; }
}