我有一个小问题,并编写了一个示例案例:
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的处理程序在再次调用Property上的'new'后是否仍然有效?或者我是否必须再次设置处理程序?
答案 0 :(得分:1)
您必须为新对象&#34; AAAA&#34;设置属性处理程序。
但是,原始对象仍将存在于内存中,并且在事件处理程序使引用保持活动状态时不会收集垃圾。如果让它继续,这将导致资源问题。您需要在对象超出范围或覆盖它之前从对象中删除事件处理程序。
答案 1 :(得分:0)
您必须再次设置处理程序。
在内部,您将委托存储在第一个ObservableCollection
实例的字段中。创建新对象意味着其字段的新值。
您也可以快速测试:
private void DoStuff()
{
Console.WriteLine("handler called");
}
var obj = new MyClass();
obj.PropertyA.Add("1");
obj.MyMethod();
obj.PropertyA.Add("1");
代码只打印一次“处理程序调用”。 (参见https://repl.it/DKjs)
的现场演示您也可以更新集合而不是替换它。
public void MyMethod()
{
var newValues = PropertyB.Where(x => true);
PropertyA.Clear();
foreach (var value in newValues)
{
PropertyA.Add(value);
}
}
这将多次打印“处理程序”(每次收集更新一次,包括删除项目,请参阅https://repl.it/DKlF的实时演示)