代码之家  ›  专栏  ›  技术社区  ›  Blam

检查C中的列表是否已更改的CPU密集型最小方法#

  •  8
  • Blam  · 技术社区  · 14 年前

    我有一个函数要被调用,如果一个列表在上次调用后发生了更改,那么实现这个列表的最佳方法是什么?

    前任:

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

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

    6 回复  |  直到 14 年前
        1
  •  13
  •   Henk Holterman    14 年前

    最有效的方法是 List<> 在您自己的类中,让所有可变方法(添加、删除)设置一个布尔标志。

    然后,您的方法可以只查看该标志并重置它。

        2
  •  19
  •   dthorpe    14 年前

    使用一个 ObservableCollection<T> 而不是列表,然后订阅 CollectionChanged 事件。

    这样,就可以知道列表何时更改,而不必扫描数据来找出事实发生后的情况。

        3
  •  5
  •   Robaticus    14 年前

    如果使用.NET 4.0,则可以使用ObservableCollection类。(在4.0之前,您需要参考WPF)。

    创建列表后,只需向CollectionChanged事件添加一个处理程序。

        4
  •  2
  •   Ani    14 年前

    你最好的选择是使用 ObservableCollection<T> BindingList<T> 以获取更改的推送通知。你也可以子类 Collection<T> 如果你想要任何习惯行为。

    要按要求回答问题(CPU密集型位除外),可以使用 List<T> :它在内部维护自己的版本,以便在枚举期间集合发生更改时可以引发。

    这是基于从Reflector分析代码。它不属于任何合同的一部分,因此随时都有可能违约。它也可能无法在部分信任环境中工作。请小心使用:

    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;
    }
    
        5
  •  1
  •   James Curran    14 年前
    • 限制对列表的访问。
    • 仅允许通过指定的API进行更改。
    • 在该API中,每当调用changeList方法时都设置一个标志。
        6
  •  1
  •   NebuSoft    14 年前

    是否尝试查看列表本身是否发生了更改(添加/删除项),或者列表中的项是否发生了更改。

    如果只是查看列表中是否添加/删除了项,最简单的方法是将列表包装到新类中,并重写对象的添加/删除方法以触发布尔值。

    更复杂的要求是,如果需要知道列表中包含的项是否已更改(列表中引用的类对象中的属性或字段)。如果是这样的话,这取决于你的具体情况。您可以在这些类的属性的setter中使用一种方法来触发一个布尔值,该布尔值将执行与以前相同的操作。但这取决于泛型列表中类的复杂性。