在分配给活动期间是否复制了代表?

时间:2010-04-26 07:32:24

标签: c# events delegates

以下代码似乎多次执行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);
        }
    }
}

2 个答案:

答案 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次。