检查列表是否已在c#中更改的最少cpu密集方法

时间:2010-09-02 19:44:09

标签: c# list

如果列表自上次调用后发生了变化,我有一个函数可以被调用,实现它的最佳方法是什么?

例如:

List<A> OurList = new List<A>();
private void Update()
{
    Boolean Changed = //?    
    if(Changed) CheckList(OurList);
}

我会假设make变量来存储旧列表并进行比较,但是如何将旧列表更新为新列表而不将其全部复制出来? (如果我进行分配,它也会更新“旧列表”)

6 个答案:

答案 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)

  • 限制对列表的访问。
  • 仅允许通过指定的API进行更改。
  • 在该API中,每当调用ChangeList方法时都设置一个标志。

答案 5 :(得分:1)

您是否正在尝试查看列表本身是否已更改(添加/删除项目),或列表中的项目是否已更改。

如果您只是想查看列表是否添加/删除了一个项目,最简单的方法是将List包装在一个新类中,并覆盖对象的Add / Remove方法以触发一个布尔值。

更复杂的要求是,如果您需要知道列表中包含的项是否已更改(列表中引用的类对象中的属性或字段)。如果是这种情况,则取决于您的具体情况。您可以为这些类的属性设置setter,以触发一个与之前相同的布尔值。但这取决于通用列表中类的复杂性。