Hsu*_*eng 20 c# delegates event-handling observer-pattern
我想在发生陷阱时向任何订户通知警报消息.
我通过委托方法(myDelegate del)制作的代码很好.
我的问题是......
我想知道是否值得使用Eventhandler更好的代理?在我的情况下,不确定委托和事件之间的区别是什么?
通知(trapinfo t),这就是我在这里所做的,以获取陷阱信息.但似乎不是一个好主意.阅读一些介绍传递委托对象的在线教程课程,是否适合我的情况?我该怎么办?有什么建议?
非常感谢 :)
我的代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
更新2013-08-12
观察者/可观察的设计模式怎么样,对我来说看起来很棒.(EventHandler)带代理 的C#observer/observable的超简单示例
就我而言,一台机器订阅了一个陷阱信使.(将计算机添加到调用列表)发生陷阱后,将消息发送到所有已订阅的计算机.(调用HandleEvent来处理它)
优点:
不再关心GetInvocationList(),只需使用(+ =)和( - =)来决定发送到哪个陷阱.
轻松理解我的程序的逻辑.
我知道有几种方法可以做到,但我希望我能分析它的优点和缺点.感谢您的意见和建议,这将非常有帮助!
我阅读了MSDN EventArgs文章,其中Matthew Watson建议使用 system.eventargs
这是我的活动版本:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
qwr*_*qwr 18
事件和委托之间的区别在于:
事件声明在委托实例上添加了一层保护.此保护可防止委托的客户端重置委托及其调用列表,并且仅允许从调用列表中添加或删除目标
2)正如我所见,您的订阅者不应该自由更改委托.一个订阅者可以分配"="而不是添加"+ =".这将分配新的委托,因此,先前的委托及其调用列表将丢失,之前的订阅者将不再叫了.所以你应该肯定使用Event.或者您可以更改代码以使您的委托变得私有,并编写其他函数来操作它.因此,这将是您自己的事件行为.
//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);
Run Code Online (Sandbox Code Playgroud)
最好使用一个event例子.
一个event由Visual Studio的窗体和WPF设计的理解,所以你可以使用IDE订阅事件.
在提升时events,您无需编写自己的foreach处理来迭代它们.
events 是大多数程序员期望访问此功能的方式.
如果您使用委托,则使用代码可能会以您希望阻止的方式(例如重置其调用列表)来处理它.events不允许这种情况发生.
至于你的第二个问题:使用event你可以创建一个派生的类EventArgs来保存数据,并在你引发它时将它传递给事件.然后消费者可以访问它.
详情请见:http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
| 归档时间: |
|
| 查看次数: |
48129 次 |
| 最近记录: |