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

10-12 15:16