我最近参加了C#的采访,在那里我被问到一个关于C#中事件和代表的问题
这个人问我什么时候说按钮被点击,这被称为第一个事件或代表?
委托是否调用事件或事件调用委托?
我们可以在c#中没有委托的事件吗?
答案 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);
}
}