[英]C# confused about delegates, publishers and subscribers
考虑以下控制台程序。 它有四个类:Program、Attacker、Defender 和 Helper。 我想从 Defender 类中删除逻辑并使用委托来调用助手。 我在这方面花了一些时间,但不太明白。
我在哪里声明我的代表:在 Program 中还是在 Defender 中? 我在哪里实例化我的委托:在程序中还是在 Defender 中? 我在哪里订阅我的委托:在程序中还是在助手中?
我可以发布我的尝试,但它不会有帮助。
using System;
namespace Delegates19
{
public class Program
{
static void Main(string[] args)
{
Attacker a = new Attacker();
string weapon = "sword";
a.Attack(weapon);
Defender d = new Defender();
d.Help(weapon);
weapon = "spear";
a.Attack(weapon);
d.Help(weapon);
}
}
public class Attacker
{
public void Attack(string s)
{
Console.WriteLine($"Attacker attacks with {s}");
}
}
public class Defender
{
public void Help(string s)
{
Console.WriteLine($"Defender is attacked with {s} and calls for help");
if (s == "sword")
Helper.Knight();
if (s == "spear")
Helper.Bowman();
}
}
public class Helper
{
public static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
public static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
}
我真的不确定您为什么要这样做,但是这些都有效并且可能会给您一些想法。
除非我了解您对事件/委托的需求,否则我实际上更喜欢您的代码而不是这些。
代表:
public class Defender
{
private static Action SwordAction = Helper.Knight;
private static Action SpearAction = Helper.Bowman;
public void Help(string s)
{
Console.WriteLine($"Defender is attacked with {s} and calls for help");
if (s == "sword")
SwordAction();
if (s == "spear")
SpearAction();
}
}
public static class Helper
{
public static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
public static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
事件:
static void Main(string[] args)
{
using (var d = new Defender())
{
d.GetHelp += StandardDefenseHelp.Defender_GetHelp;
d.Help("sword");
d.Help("spear");
}
}
public class Defender : IDisposable
{
public event EventHandler<string> GetHelp;
private void RaiseGetHelp(string weapon) => GetHelp?.Invoke(this, weapon);
public void Help(string weapon)
{
Console.WriteLine($"Defender is attacked with {weapon} and calls for help");
RaiseGetHelp(weapon);
}
public void Dispose()
{
GetHelp = null;
}
}
public static class StandardDefenseHelp
{
public static void Defender_GetHelp(object sender, string weapon)
{
if (weapon == "sword")
Knight();
if (weapon == "spear")
Bowman();
}
private static void Knight()
{
Console.WriteLine($"Knight charges Attacker");
}
private static void Bowman()
{
Console.WriteLine($"Bowman shoots Attacker");
}
}
重要:事件通常是内存泄漏的原因,这就是为什么 Defender 现在是一次性的。
如果您有多个“DefenseHelp”类型,则上述设计可能很有用,并且当防御者需要帮助而防御者本身一无所知时,也应该发生其他事情。
但我只会这样做,如果它带来了一些好处。 我相信 KISS 开发方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.