为什么List属性中的编辑方法使用get访问器?

问题描述 投票:0回答:3

我有一个

List<T>
类型的属性,我想在数据库更新时更新它。

起初,我以为我可以在属性的设置访问器中更新数据库,但经过一些测试,我意识到像

Add()
Remove()
这样的方法只使用get访问器,而不是set访问器。

为什么会这样,我该怎么做才能解决它?

包含此属性的类实现了一个需要

List
的接口。虽然我可以在界面中将属性的类型更改为
BindingList
,但并不是所有的实现成员都需要知道属性何时更新。

c# properties
3个回答
0
投票

您的房产一开始就不应该有二传手。该属性与

List
对象本身有关,而不是
List
中的项目。 setter 将用于用全新的
List
对象替换现有的
List
对象。为了在现有的
Add
对象上调用
Remove
List
,您需要先从属性中获取该对象,因此执行的是 getter。

如果你需要知道现有集合对象何时发生变化,只有集合本身可以做到。这意味着按照您的建议使用

BindingList<T>
,或
ObservableCollection<T>
。该属性本身应该是只读的,例如

public ObservableCollection<object> Objects { get; } = new ObservableCollection<object>();

private void Objects_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // ...
}

和:

Objects.CollectionChanged += Objects_CollectionChanged;

更多内容……


0
投票

创建 4 个 CRUD 方法并对其进行单元测试可能更容易,因为您经常需要这样做。但是,如果你真的想要一个解决方法,你可以使用 IList:

public class DatabaseList<T>: IList<T>
    where T: class, new()
{
    private List<T> _list;
        
    public DatabaseList()
    {
        _list = new List<T>();
        // populate from current database content?
    }

    public new void Add(T item)
    {
        _list.Add(item);
        // and do database Insert
    }
    
    // and the other 12 members of IList...
    //   which makes the 4 CRUD methods sounds like a lot less testing
}

0
投票

我将首先使用代码片段重述问题,以便我们使用实际的标识符名称。


你有这样一个类:

public class MyClass
{
    public List<string> MyList {get; set;} = new List<string>();
}

你有一个

MyClass
的实例:

var myInstance = new MyClass();

然后你有这样的代码:

myInstance.MyList.Add("foo");

问题是为什么这使用

get
访问器而不是
set
,即使它改变了
List<string>
属性。


答案是代码从

myInstance
对象开始,然后需要 GET
List<string>
属性引用的
MyList
对象,以便它可以调用该列表的
Add()
方法。
 方法更改列表并不重要
。就属性访问而言,您仍然是 getting 参考,仅此而已。

那么

Add()
访问器有什么用呢?好吧...设置参考。所以现在假设你这样做:

set

这使用了

myInstance.MyList = new List<string>();
访问器,因为 它为实际属性设置了一个新值,而不仅仅是属性或属性的成员。现在您了解了
set
访问器何时实际被调用,希望这有助于澄清 为什么
set
访问器用于其他情况:您确实 没有 为属性分配新值。


最后,这应该提出一个问题,即您是否想要一个

get
属性访问器。

对于许多类,完全更改类使用的列表可能会破坏类其他相关方面的假设。也就是说,您最好像这样声明属性:

set

或者像这样:

public class MyClass
{
    public List<string> MyList {get; private set;} = new List<string>();
}

因为,再一次,任何你想用特定列表实例做的事情都是一个

public class MyClass
{
    public List<string> MyList {get;} = new List<string>();
}
操作,而不是一个
get
,所以
set
访问并不是真正需要的甚至有用。

© www.soinside.com 2019 - 2024. All rights reserved.