如果列表自上次调用后发生了变化,我有一个函数可以被调用,实现它的最佳方法是什么?
例如:
List<A> OurList = new List<A>();
private void Update()
{
Boolean Changed = //?
if(Changed) CheckList(OurList);
}
我会假设make变量来存储旧列表并进行比较,但是如何将旧列表更新为新列表而不将其全部复制出来? (如果我进行分配,它也会更新“旧列表”)
答案 0 :(得分:19)
使用ObservableCollection<T>
代替List,然后订阅CollectionChanged
事件。
通过这种方式,您将被告知何时更改列表,而不必扫描数据以确定事后发生的事情。
答案 1 :(得分:13)
最有效的方法是将List<>
包装在您自己的类中,并让所有变异方法(Add,Remove)设置一个布尔标志。
然后,您的方法可以查看该标志并重置它。
答案 2 :(得分:5)
如果您使用的是.NET 4.0,则可以使用ObservableCollection类。 (在4.0之前,您需要引用WPF)。
创建列表后,只需向CollectionChanged事件添加处理程序。
答案 3 :(得分:2)
您最好的选择是使用ObservableCollection<T>
或BindingList<T>
来获取更改的推送通知。如果您想要任何自定义行为,也可以继承Collection<T>
。
要按照要求回答您的问题(cpu密集位除外),您可以使用List<T>
的现有功能:它在内部维护自己的版本,以便在枚举期间集合发生变化时可以抛出
这是基于分析来自反射器的代码。它不是任何合同的一部分,因此它可能随时中断。它也可能在部分信任环境中不起作用。请小心使用:
public static int GetVersion<T>(this List<T> list)
{
return (int)list.GetType()
.GetField("_version", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(list);
}
...
private int _lastCheckedVersion = 0;
private void Update()
{
int currentVersion = ourList.GetVersion();
if(currentVersion != _lastCheckedVersion) CheckList(ourList);
_lastCheckedVersion = currentVersion;
}
答案 4 :(得分:1)
答案 5 :(得分:1)
您是否正在尝试查看列表本身是否已更改(添加/删除项目),或列表中的项目是否已更改。
如果您只是想查看列表是否添加/删除了一个项目,最简单的方法是将List包装在一个新类中,并覆盖对象的Add / Remove方法以触发一个布尔值。
更复杂的要求是,如果您需要知道列表中包含的项是否已更改(列表中引用的类对象中的属性或字段)。如果是这种情况,则取决于您的具体情况。您可以为这些类的属性设置setter,以触发一个与之前相同的布尔值。但这取决于通用列表中类的复杂性。