事件和委托顺序当事件被触发时
本文关键字:事件 顺序 | 更新日期: 2023-09-27 18:11:31
我最近参加了一个c#的面试,在那里我被问到一个关于c#中的事件和委托的问题
这个人问我当一个事件按钮被点击时,哪个被称为第一个事件还是第一个委托?
是委托调用事件还是事件调用委托?
在c#中我们可以有一个没有委托的事件吗?那个人问我当一个事件按钮被点击时,哪个先被调用:事件还是委托?
当你打开一扇门时,谁先被打开:门还是门把?
啊?
那个问题没有任何意义。你用门把手打开一扇门,但是你不打开门把手。
调用事件是什么意思?事件不是你可以称之为的东西。事件是你引发的事情。引发事件与调用委托相同。
是委托调用事件还是事件调用委托?
是门打开门把手,还是门把手打开门?
同样,这个问题没有意义。门把手不是可以"打开"的东西,门把手不打开门——你通过握住门把手来打开门。
委托是否调用事件?没有;事件不是可以被"称为"的东西。事件是否调用委托?不,引发事件的代码调用委托。
在c#中我们可以有一个没有委托的事件吗?
是的,从某种意义上说,与事件相关联的委托引用可以是空引用。但是每个事件都与一个委托类型相关联,并且以某种方式关联了一个对委托的引用。
在我看来,整套问题表明提问者对事件和代表之间的关系没有很好的理解。考虑这个问题的一个好方法是,事件只是一个包含对多播委托引用的属性。属性具有获取和设置属性值的特殊方法,而事件具有向多播委托添加和删除委托的特殊方法。
事件是一个概念,它利用委托作为一种手段来调用订阅了它们的方法。
事件本身不被调用。当一段代码引发事件时,它将通过调用委托来调用每个订阅的方法。
引发事件,调用委托。因此,当单击该按钮时,将引发一个buttonClick
事件,这意味着将根据订阅顺序调用订阅该事件的每个委托。
事件只是在。net中作为多强制转换委托实现的代码结构。
当一个事件被"raise "时(这只能由与该事件相同类中的代码完成);事件引发必须在"受保护的"范围内发生),委托以同步方式一次调用一个,但不一定以任何确定的顺序调用。事件是委托,因此当按钮被单击引发事件时,委托由运行时调用,运行时接收到用户在GUI区域单击按钮的Windows消息。
语句"事件被引发"answers"委托被调用"是等价的语句;这就像在问"鸡和家鸡哪个更重要?"。
现在,事件经常级联,特别是当我们谈论UI时。有一个MouseUp事件,在鼠标按钮被释放时调用,它可以触发一个或多个其他事件,如MouseClick、MouseDoubleClick、DragDrop等。你可能不会将处理程序附加到MouseUp事件,但是在MouseUp的幕后有内置的逻辑来引发你处理的MouseClick事件。所以,在这个意义上,你可以说MouseUp事件"先出现"并调用MouseClick处理程序委托。
这个页面出现在谷歌搜索结果的顶部,所以如果你也登陆这里,下面是一些你可能会发现有用的东西。多播委托在一个线程上按分配顺序以确定的顺序调用(参见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);
}
}