事件和代表在触发事件时进行排序

时间:2011-10-18 15:39:53

标签: c# .net

我最近参加了C#的采访,在那里我被问到一个关于C#中事件和代表的问题

这个人问我什么时候说按钮被点击,这被称为第一个事件或代表?

委托是否调用事件或事件调用委托?

我们可以在c#中没有委托的事件吗?

5 个答案:

答案 0 :(得分:10)

  

这个人问我什么时候说按钮被点击,首先被调用:事件或代表?

当您打开首先打开的门时:门把手

咦?

这个问题没有任何意义。你用一个门把手打开一扇门,但你没有打开一个门把手

“召集”活动意味着什么?事件不是你打电话的事情。事件是你筹集的东西。引发事件与调用委托的相同。

  

委托是否调用事件或事件调用委托?

门是否打开门把手,或门把手是否打开门?

同样,这个问题没有意义。门把手不是可以“打开”的东西,并且门把手没有打开门 - 打开门,拿着门把手。

代表是否致电该活动?没有;事件不是可以被“召唤”的事物。该事件是否会调用该委托?不,提升事件的代码调用委托

  

我们可以在c#中没有委托的事件吗?

是的,在某种意义上,与事件关联的委托引用可以是空引用。但是每个事件都与委托类型相关联,并以某种方式与委托相关联。

整套问题向我表明提问者对事件与代表之间的关系没有很好的理解。考虑它的一个好方法是,事件只是一个包含对多播委托的引用的属性。虽然属性具有获取和设置属性值的特殊方法,但事件具有向多播委托添加和删除委托的特殊方法。

答案 1 :(得分:5)

事件是一个概念,它使用委托作为调用已订阅它们的方法的手段。

事件本身不会被调用。当一段代码引发一个事件时,它将通过调用委托来调用每个订阅的方法。

答案 2 :(得分:1)

引发事件,调用代理。因此,当单击该按钮时,会引发buttonClick事件,这意味着将根据订阅顺序调用订阅该事件的每个代理。

答案 3 :(得分:0)

事件只是在.NET中作为多播委托实现的代码构造。

当事件被“引发”时(只能通过与事件相同的类中的代码来完成;事件提升必须在“受保护”范围内发生),一次一个地调用委托,同步方式但不一定是任何确定性的顺序。事件是委托,因此当为单击的按钮引发事件时,运行时调用委托,运行时已收到用户在按钮的GUI区域上单击的Windows消息。

“引发事件”和“调用委托”的陈述是等同的陈述;这就像问“哪个先来,鸡还是 gallus domesticus ?”。

现在,事件经常级联,特别是当我们谈论UI时。有一个MouseUp事件,在释放鼠标按钮时调用,可以触发一个或多个其他事件,如MouseClick,MouseDoubleClick,DragDrop等。您可能不会将处理程序附加到MouseUp事件,但有内置逻辑在MouseUp幕后提升你要处理的MouseClick事件。因此,从这个意义上讲,您可以说MouseUp事件“首先出现”并调用MouseClick处理程序委托。

答案 4 :(得分:0)

这个页面在Google搜索结果的顶部冒出来,所以如果你也在这里,你可能会觉得有用。多播委托在一个线程上按照确定的顺序调用(参见MSDN),按赋值顺序。这个赋值将涉及某种类型的数组,并且索引填满不合规定是不合逻辑的。

public partial class Form1 : Form
{
    ob<Control>ob1;
    ob<Control>ob2;
    ob<Control>ob3;

    public Form1()
    {
        InitializeComponent();

        ob<Control>.setup(button1);
        ob1 = new ob<Control>(1, true);
        ob2 = new ob<Control>(2, false);
        ob3 = new ob<Control>(3, false);
    }

    public class ob<T> where T : Control
    {
        int ndx;
        Boolean isSentinel;
        static Boolean dontdostuff;
        static T c;
        public static void setup(T c) {ob<T>.c = c;}//an argument less from constructor, useful for many objects (more likely to be menuitems)

        public ob(int ndx, Boolean isSentinel)
        {
            this.ndx = ndx;
            this.isSentinel = isSentinel;
            c.Click += new EventHandler(click);
        }

        void click(object sender, EventArgs e) 
        { 
                    if( isSentinel)
                    {
                        if (MessageBox.Show("ob" + ndx + " asks:  short circuit subsequent delegate calls?", "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                        {
                            dontdostuff = true;
                            return;
                        }
                        else
                        {
                            dontdostuff = false;
                        }   
                    }
                    else
                    {
                        if( dontdostuff) return;
                    }
                 MessageBox.Show("ob" + ndx + " doing stuff in order of handler addition", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }