以下代码似乎多次执行FileRetrieved事件。我认为代表是参考类型。我期望这个执行一次。我要猜测一下,该引用是按值传递的,因此被复制了,但我不喜欢猜测:-)
public delegate void DirListEvent<T>(T dirItem);
void Main()
{
DirListEvent<string> printFilename = s => {
Console.WriteLine (s);
};
var obj = new DirectoryLister();
obj.FileRetrieved += printFilename;
obj.FileRetrieved += printFilename;
obj.GetDirListing();
}
public class DirectoryLister {
public event DirListEvent<string> FileRetrieved;
public DirectoryLister() {
FileRetrieved += delegate {};
}
public void GetDirListing() {
foreach (var file in Directory.GetFiles(@"C:\"))
{
FileRetrieved(file);
}
}
}
最佳答案
基本上,每个委托实例都带有一个调用列表,该列表实质上只是与您关联的目标事件的所有引用的列表。例如,
public event DirListEvent<string> FileRetrieved;
上面的代码创建了一个称为FileRetrieved的委托类型(如您所知)。
现在,此委托类型具有一个调用列表,该列表保留使用+ =运算符或Delegate.Combine方法注册的所有委托实例。
obj.FileRetrieved += printFilename;
obj.FileRetrieved += printFilename;
此代码基本上将2个相同的委托实例添加到FileRetrieved调用列表中。调用列表允许重复的实例。因此,在调用FileRetrieved时,它将遍历其调用列表,并发现添加了2个方法(均为printFilename),并且只需按预期的方式将调用委派给printFilename。
尝试使用
obj.FileRetrieved += printFilename;
的另一行,FileRetrieved应该调用printFilename 3次。关于c# - 在分配给事件期间会复制代表吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2711735/