gpt4 book ai didi

C# 委托(delegate)与事件处理器

转载 作者:IT王子 更新时间:2023-10-29 04:43:30 25 4
gpt4 key购买 nike

我想在发生陷阱时向所有订阅者发送警报消息。

我创建的代码使用委托(delegate)方法 myDelegate del 运行良好。

我的问题是:

  1. 我想知道使用 EventHandler 代替委托(delegate)是否更好?在我的例子中,我不确定委托(delegate)和 EventHandler 之间有什么区别。

  2. notify(trapinfo t),这就是我在这里获取陷阱信息所做的。但这似乎不是一个好主意。我阅读了一些介绍传递委托(delegate)对象的在线教程类(class);我想知道这是否适合我的情况?我应该怎么做?有什么建议吗?

非常感谢:)

我的代码:

public class trapinfo
{
public string info;
public string ip;
public string cause;
}

public class trap
{
public delegate void myDelegate(trapinfo t);
public myDelegate del;

trapinfo info = new trapinfo();

public void run()
{
//While(true)
// If a trap occurred, notify the subscriber
for (; ; )
{
Thread.Sleep(500);
foreach (myDelegate d in del.GetInvocationList())
{
info.cause = "Shut Down";
info.ip = "192.168.0.1";
info.info = "Test";
d.Invoke(info);
}
}
}
}
public class machine
{
private int _occuredtime=0;

public trapinfo info = new trapinfo();
public void notify(trapinfo t)
{
++_occuredtime;
info.cause = t.cause;
info.info = t.info;
info.ip = t.ip;
getInfo();
}
public void subscribe(trap t)
{
t.del += new trap.myDelegate(notify);
}
public void getInfo()
{
Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
info.cause, info.info, info.ip,_occuredtime);
}
}
class Program
{
static void Main(string[] args)
{
trap t = new trap();
machine machineA = new machine();
machineA.subscribe(t);
t.run();
}
}

更新 2013-08-12

observer/observable怎么样?设计模式,在我的案例中看起来很棒 (EventHandler)。

在我的例子中,一台机器订阅了一个陷阱信使。 (将机器添加到调用列表)一旦发生陷阱,我就会向所有订阅的机器发送一条消息。 (调用HandleEvent进行处理)

优点:

  • 不再关心GetInvocationList(),只用(+=)(-=)来决定向谁发送陷阱。

  • 更容易理解我的程序逻辑。

我知道有几种方法可以做到,但我希望我能分析一下它的优缺点。

感谢您的意见和建议,这将非常有帮助!

我读了MSDN EventArgs Matthew Watson 建议的文章。

这是我的事件版本:

public class TrapInfoEventArgs : EventArgs
{
public int info { get; set; }
public string ip { get; set; }
public string cause { get; set; }
}
public class trap
{
public event EventHandler<TrapInfoEventArgs> TrapOccurred;

protected virtual void OnTrapOccurred(TrapInfoEventArgs e)
{
EventHandler<TrapInfoEventArgs> handler = TrapOccurred;
if (handler != null)
{
handler(this, e);
}
}


public void run()
{
//While(true)
// If a trap occurred, notify the subscriber
for (; ; )
{
Thread.Sleep(500);
TrapInfoEventArgs args = new TrapInfoEventArgs();
args.cause = "Shut Down";
OnTrapOccurred(args);
}
}
}
public class machine
{
public void c_TrapOccurred(object sender, TrapInfoEventArgs e)
{
Console.WriteLine("<Alert>: cauese/{0}, info/ {1}, ip/{2}, time/{3}",
e.cause, e.info, e.ip, DateTime.Now.ToString());
}
}
class Program
{
static void Main(string[] args)
{
trap t = new trap();
machine machineA = new machine();
t.TrapOccurred += machineA.c_TrapOccurred; //notify machine A
t.run();
}
}

最佳答案

事件和委托(delegate)的区别在于:

event declaration adds a layer of protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list, and only allows adding or removing targets from the invocation list

参见 What are the differences between delegates and events?

2) 在我看来,您的订户不应随意更换委托(delegate)。一个订阅者可以将 = 分配给它,而不是添加 +=。这将分配一个新的委托(delegate),因此,先前的委托(delegate)及其调用列表将丢失,并且不再调用以前的订阅者。所以你肯定应该使用 Event 。或者您可以更改您的代码以将您的委托(delegate)设为私有(private)并编写其他函数来操纵它以定义您自己的事件行为。

 //preventing direct assignment
private myDelegate del ;

public void AddCallback(myDelegate m){
del += m;
}

public void RemoveCallback(myDelegate m){
del -= m;
}

//or
public static trap operator +(trap x,myDelegate m){
x.AddCallback(m);
return x;
}
public static trap operator -(trap x, myDelegate m)
{
x.RemoveCallback(m);
return x;
}

//usage

//t.AddCallback(new trap.myDelegate(notify));
t+=new trap.myDelegate(notify);

关于C# 委托(delegate)与事件处理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18170282/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com