为什么List <T> .Add是只读属性中的读取机制?

HaM*_*MeD 0 c# properties

也许这只是一个误解,但对我来说这是一个很大的问题.让我来解释一下:

根据参考,属性是机制而不是字段.一种为字段提供读写函数的机制,根据这种机制,我们可以使用getset访问器创建只读,只写或读写属性.

现在实现在这里:

public class Foo
{
    private List<string> _bar;

    public List<string> Bar
    {
        get
        {
            return _bar;
        }
    }

    public Foo()
    {
        _bar = new List<string>();
        _bar.Add("string1");
    }
}
Run Code Online (Sandbox Code Playgroud)

Foo类中,我们有一个只读属性(Bar),它由一个字符串组成.

现在让我们为这个类添加一个驱动程序:

static void Main(string[] args)
{
    Foo fooObj = new Foo();
    fooObj.Bar.Add("string2");

    foreach (string s in fooObj.Bar)
    {
        Console.WriteLine(s);
    }

    Console.ReadLine();

}
Run Code Online (Sandbox Code Playgroud)

这是一个很大的问号: 为什么Bar财产不是只读的?

输出:

srring1
string2
Run Code Online (Sandbox Code Playgroud)

我知道如何创建一个只读集合(我的问题不是为什么List<T>不是只读的),我需要一个关于只读属性的解释.

Jam*_*mes 5

那么该Bar 属性是只读的,即它不能直接设置

fooObj.Bar = new List<string>(); // compiler error
Run Code Online (Sandbox Code Playgroud)

但是,该属性返回的数据不是

fooObj.Bar.Add("..."); // is fine
Run Code Online (Sandbox Code Playgroud)

需要理解的是,属性上的修饰符决定了如何从对象访问它,它对属性的基础数据没有直接影响.因此,从只读属性返回引用类型与从读/写属性返回引用类型完全相同.

在您的示例中,如果您希望它Bar是只读的,那么您可以返回一个ReadOnlyCollection<T>不可变的集合,而不是一个List<T>.

private List<string> _bar;
...
public void Add(string item)
{
    _bar.Add(item);
}

public IEnumerable<string> Bar
{
    get { return new ReadOnlyCollection<string>(_bar); }
}
Run Code Online (Sandbox Code Playgroud)

这将使用包含对象保持对列表的控制,但允许您返回列表本身的只读副本.