每次修改List(不访问)时运行方法

时间:2016-01-06 12:10:27

标签: c# list

这与问题非常相似,但具体针对列表。

How to trigger event when a variable's value is changed?

每次我的列表已修改时,我想运行一个方法。

我假设使用属性并在'set'中放置一个方法将是解决此问题的正确方法。我开始用这样的东西

public class Stuff
{
   private List<Things> _myThings;

   public List<Things> MyThings
    {
        get 
        {
            return _myThings;       
        }
        private set
        {
            _myThings= value;
            runWhenListIsChanged();
        }
    }
}

但是,当我使用'RemoveAt'或'RemoveRange'这样的命令时

public class StuffChanger
{
    Stuff.MyThings.RemoveAt(5);
}

直接进入'get'属性并更改列表。

我错误地认为它会使用set(因为它改变了列表)但事实并非如此。调试时(使用Visual Studio中的“step into”工具)我注意到可以使用'get'访问器修改List。

在这种特殊情况下,我不希望每次读取列表时都调用一个方法,因为这会导致性能增加或导致堆栈溢出。所以这不是一个选择。

如果有人有任何提示或代码建议,我将非常感激!非常感谢。

1 个答案:

答案 0 :(得分:2)

正如您所观察到的,您编写的用于操作列表的代码确实没有在属性中设置新列表。

相反,这段代码:

Stuff.MyThings.RemoveAt(5);

可以被认为与此类似:

var list = Stuff.MyThings;
list.RemoveAt(5);

因此,它从getter中读取列表,然后直接操作列表本身。

要在列表本身发生变化时收到通知,您需要使用List<T>以外的其他内容,因为此类型没有任何支持该要求的功能。

一个好的候选人将是ObservableCollection<T>,你可以将事件处理程序连接到CollectionChanged事件。

请注意,这只会观察列表的更改,而不会查看列表中的元素。如果您在列表中添加或删除项目,您将收到通知,但如果您执行以下代码:

MyStuff.MyThings[0].SomeProperty = SomeNewValue;

然后你不会从列表中获得任何通知。您将不得不在元素类型上实现类似INotifyPropertyChanged的内容,并将事件处理程序与其挂钩以获取这些通知。