Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 触发事件时事件和委托的顺序_C#_.net - Fatal编程技术网

C# 触发事件时事件和委托的顺序

C# 触发事件时事件和委托的顺序,c#,.net,C#,.net,我最近参加了在C#的一次采访,在采访中,我被问到了一个关于C#活动和代表的问题# 那个人问我什么时候点击了一个事件按钮,哪个被称为第一个事件或委托 委托是调用事件还是事件调用委托 在c#中是否可以有一个没有委托的事件?事件是一个概念,它利用委托作为调用已订阅方法的手段 事件本身不被调用。当一段代码引发事件时,它将通过调用委托来调用每个已订阅的方法。引发事件时,将调用委托。因此,当单击按钮时,将引发一个按钮单击事件,这意味着将根据订阅顺序调用订阅该事件的每个代理 那个人问我什么时候点击了一个事件按

我最近参加了在C#的一次采访,在采访中,我被问到了一个关于C#活动和代表的问题#

那个人问我什么时候点击了一个事件按钮,哪个被称为第一个事件或委托

委托是调用事件还是事件调用委托


在c#中是否可以有一个没有委托的事件?

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


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

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

那个人问我什么时候点击了一个事件按钮,哪个先被调用:事件还是委托

当你打开一扇门时,哪个先被打开:门还是门把手

那个问题毫无意义。你用门把手开门,但你没有打开门把手

“调用”事件意味着什么?事件不是你所说的事情。事件是你提出的事情。引发事件与调用委托相同

委托是调用事件还是事件调用委托

门是打开门把手,还是门把手打开了门

同样,这个问题没有意义。门把手不是可以“打开”的东西,门把手也不能开门——你可以通过握住门把手来开门

代理是否调用该事件?不事件不是可以“称为”的事物。事件是否调用委托?否,引发事件的代码调用委托

我们可以在c#中没有委托的情况下进行活动吗

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


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

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

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

“引发事件”和“调用委托”是等效语句;这就像问“鸡还是家鸡,谁先来?”


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

此页面在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);
        }
    }
公共部分类表单1:表单
{
obob1;
obob2;
obob3;
公共表格1()
{
初始化组件();
观察设置(按钮1);
ob1=新ob(1,真);
ob2=新ob(2,错误);
ob3=新ob(3,错误);
}
公共类ob,其中T:Control
{
int-ndx;
布尔isSentinel;
静态布尔运算;
静态tc;
publicstaticvoidsetup(tc){ob.c=c;}//构造函数中的一个参数较少,对许多对象有用(更可能是menuitems)
公共对象(整数ndx,布尔isSentinel)
{
这是ndx=ndx;
this.isSentinel=isSentinel;
c、 单击+=新建事件处理程序(单击);
}
无效单击(对象发送者,事件参数e)
{ 
如果(isSentinel)
{
if(MessageBox.Show(“ob”+ndx+“asks:短路后续代理调用?”,“”,MessageBoxButtons.OK取消,MessageBoxIcon.Question)=DialogResult.OK)
{
dontdostuff=真;
返回;
}
其他的
{
dontdostuff=false;
}   
}
其他的
{
如果(不)返回;
}
MessageBox.Show(“ob”+ndx+“按照处理程序添加的顺序做事情”,”,MessageBoxButtons.OK,MessageBoxIcon.Information);
}
}

事件的概念是直接建立在代理概念之上的,因此您的问题对我来说没有意义。事件不会被“调用”