调用&;new&;之后,eventandler会发生什么?

本文关键字:什么 new 之后 调用 eventandler | 更新日期: 2023-09-27 18:05:25

我有一个小问题,并编了一个例子:

 public class MyClass
{
    private ObservableCollection<string> PropertyA { get; set; }
    private ObservableCollection<string> PropertyB { get; set; }
    public MyClass()
    {
        PropertyA = new ObservableCollection<string>();
        PropertyA.CollectionChanged += (sender, e) => DoStuff();
        PropertyA.Add("AAAA");
        PropertyB = new ObservableCollection<string>();
        PropertyB.Add("BBBB");
        MyMethod();
    }
    private void MyMethod()
    {
        PropertyA = new ObservableCollection<string>(PropertyB.Where('some linq expression'));
        //does PropertyA still have its CollectionChanged handler from here on?    
    }
}

正如你可能从我的评论中看到的问题是:我的PropertyA的处理程序在再次对属性调用'new'后仍然工作吗?还是我必须重新设置处理程序?

调用&;new&;之后,eventandler会发生什么?

您必须为新对象"AAAA"设置属性处理程序。

但是,原始对象仍然存在于内存中,并且不会被垃圾收集,因为事件处理程序保持引用存活。如果让它继续下去,这将导致资源问题。您需要在对象超出范围或覆盖它之前从对象中删除事件处理程序。

您必须重新设置处理程序。

在内部,您将委托存储在第一个ObservableCollection实例的字段中。创建一个新对象意味着它的字段有新的值。

你也可以快速测试:

private void DoStuff()
{
    Console.WriteLine("handler called");
}
var obj = new MyClass();
obj.PropertyA.Add("1");
obj.MyMethod();
obj.PropertyA.Add("1");

代码将只打印一次"handler called"。(参见现场演示https://repl.it/DKjs)

你也可以更新集合而不是替换它。

public void MyMethod()
{
    var newValues = PropertyB.Where(x => true);
    PropertyA.Clear();
    foreach (var value in newValues)
    {
        PropertyA.Add(value);
    }
}

这将多次打印"handler called"(每次集合更新一次,包括删除项,参见https://repl.it/DKlF的实时演示)