C#委托v.s.事件处理程序 [英] C# delegate v.s. eventHandler

查看:109
本文介绍了C#委托v.s.事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我通过委托方法(myDelegate del)可以正常工作。 p>

我的问题是..


  1. 我想知道是否值得使用Eventhandler更好的委托?
    不知道代理和事件在我的情况下有什么不同?


  2. 通知(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)
//如果发生陷阱,通知订阅者
for(;; )
{
Thread.Sleep(500);
foreach(myDelegate d in del.GetInvocationList())
{
info.cause =关闭;
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);
}
}
类程序
{
static void Main(string [] args)
{
trap t = new trap() ;
机床A =新机();
machineA.subscribe(t);
t.run();
}
}

更新2013-08-12



观察者/可观察的设计模式,对我来说看起来不错。 (EventHandler)
超简单的例子C#观察者/可与代表观察



在我的情况下,机器订阅陷阱信使。 (将机器添加到调用列表)
发生陷阱后,将消息发送到所有订阅的机器。 (Call HandleEvent处理它)



优势:




  • 不要关心GetInvocationList(),只需使用(+ =)和( - =)来决定谁发送到。


  • 轻松理解我的程序。




我知道会有几种方法来做,但我希望我可以分析其职业和利弊。
感谢您的意见和建议,这将非常有用!


我阅读了MSDN EventArgs Matthew Watson建议的文章b $ b system.eventargs


以下是我的活动版本:

  public class TrapInfoEventArgs:EventArgs 
{
public int info {get;组; }
public string ip {get;组; }
public string cause {get;组; }
}
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)
//如果陷阱发生,通知用户
(;;)
{
Thread.Sleep(500);
TrapInfoEventArgs args = new TrapInfoEventArgs();
args.cause =关闭;
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());
}
}
类程序
{
static void Main(string [] args)
{
trap t = new trap() ;
机床A =新机();
t.TrapOccurred + = machineA.c_TrapOccurred; //通知机器A
t.run();
}
}


解决方案

事件和委托之间的区别是:


事件声明在委托实例上添加了一层保护。
此保护防止代理的客户端重置
委托及其调用列表,并且只允许从调用列表添加或删除
目标




请参阅什么是代表和事件之间的差异?



2)我看到你的订阅者不应该自由地更改委托。一个订阅者可以分配=而不是添加 + =。这将分配新的委托,因此,以前的委托与其调用列表将丢失,以前的订阅者将不会再调用。所以你应该使用事件肯定。或者您可以更改代码以使您的代理私有,并编写其他功能来进行操作。这将是您自己的事件行为。

  //防止直接赋值
private myDelegate del;

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

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

//或
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;
}

//用法

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


I want to notify an alert message to any subscribers when an trap occurred.

The code i made works fine through a delegate method(myDelegate del).

my questions are..

  1. I want to know is it worth using Eventhandler better off delegate? not sure what's different between delegate and event exactly in my case?

  2. notify(trapinfo t), that's what I've done here, to get trap information. But it seems not to be a good idea. Read some online tutorial lesson introducing passing delegates object, is it appropriate to my case? And How should I do? Any suggestions?

Thanks a lot :)

My code:

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();
        }
    }

Update 2013-08-12

How about observer/observable design pattern, that looks great to my case. (EventHandler) Super-simple example of C# observer/observable with delegates

In my case, a machine subscribe a trap messenger. (Add machine to a invocation list) Once a trap occurred, send message to all machines which are subscribed. (Call HandleEvent to handle it)

Advantage:

  • don't care GetInvocationList() anymore, just use (+=) and (-=) to decide who trap send to.

  • Easily to understand the logic of my program.

I know there would be several ways to do it, but I wish I could analyze its pros and cons. And Thanks for your comments and suggestions, that would be very helpful!

I read MSDN EventArgs Article which Matthew Watson suggests system.eventargs

Here's my Event Version:

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();
    }
}

解决方案

The difference between event and delegate is that :

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

See What are the differences between delegates and events?

2) As I see your subscriber should not change delegate freely.One subscriber can assign "=" it instead of adding "+=" .This will assign new delegate ,therefore, previous delegate with its invocation list will be lost and previous subscribers will not called anymore. So you should use Event for sure. or you can change your code to make your delegate private and write additional functions for manipulating it .so it will be your own event behavior .

 //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#委托v.s.事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆