以下代码似乎多次执行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);
}
}
}
答案 0 :(得分:3)
实际上,FileRetrieved是一组委托,同一个委托可以多次出现在此集合中。不是所有的集合都是集合......
答案 1 :(得分:0)
基本上,每个委托实例都带有一个调用列表,它实际上只是与您关联的目标事件的所有引用的列表。例如,
public event DirListEvent<string> FileRetrieved;
上面的代码创建了一个名为FileRetrieved的委托类型(如您所知)。 此委托类型现在有一个调用列表,它使用+ = operator或Delegate.Combine方法保存您注册的所有委托实例。
obj.FileRetrieved += printFilename;
obj.FileRetrieved += printFilename;
此代码基本上将2个相同的委托实例添加到FileRetrieved调用列表中。 调用列表允许重复实例。因此,当调用FileRetrieved时,它会通过其调用列表并发现添加了2个方法(都是printFilename)并且只是将对printFilename的调用委托给它做。
尝试使用另一行obj.FileRetrieved += printFilename;
并且FileRetrieved应该调用printFilename 3次。