这些代表是垃圾收集的吗?

时间:2017-01-24 11:51:31

标签: c# delegates garbage-collection

我有一个类,它公开了一个用于“注册”委托的方法(这些委托被称为后续过程的一部分)。传递给该方法的委托包装在一个小对象中,然后将该对象添加到字典中。该方法看起来像这样: -

public void Add(int id, Func<bool> someDelegate)
{
    var wrapper = new MyDelegateWrapper(someDelegate);
    _wrappers.Add(id, wrapper); // _wrappers is a Dictionary<>
}

一段时间后,我可能决定通过调用这样的方法来“取消注册”代表: -

public void Remove(int id)
{
    _wrappers.Remove(id);
}

我很想知道这段代码是否引入了任何GC问题。即它会阻止“包装器”对象或创建该委托的对象进行GC吗?调用对象是通过匿名委托还是传递给自己的“真实”方法,这会有所不同吗?

2 个答案:

答案 0 :(得分:2)

委托不是COM对象。它们不需要实现git rm --cached . -r,并且在GC认为合适时会被垃圾收集。

因此,只要它们不再可以从其他.NET对象访问,它们就会被标记为收集,并在CLR需要清空空间时收集。

答案 1 :(得分:1)

GC从不收集的对象中收集没有传入引用的所有对象。这是通过从堆栈和静态字段中的所有引用创建对象图来实现的。如果对象具有对另一个对象的传出引用,则这不会阻止垃圾回收。

向事件添加处理程序时,会从包含事件的对象创建包含事件侦听器的对象的引用。这并不会阻止收集事件的对象。

唯一的例外是当您在方法语法中实现事件时(即使用addremove方法)并使用{{1中的事件处理程序创建从侦听器到对象的引用}} 方法。然而,那将是非常不寻常的。