C# - 在参考类型上使用公共Getter的私人设置器



使用公共getter和私人设定器考虑以下简短代码示例:

public class Foo        
{
    public class Bar
    {
        ...
    }
    public Bar fooBar { get; private set; }
    public int valueType { get; private set; }
}

我想确保只能从Foo类内写入类成员。在上面的示例中,它适用于诸如valueType之类的值类型。但是,诸如嵌套类fooBar之类的参考类型如何表现?

我可以使用公共getter返回的参考,操纵我的私人会员吗?

如果您所指的类型是可变的,那么,是的,任何具有"容器"的人都可以获取参考然后突变对象。例如:

using System;
using System.Collections.Generic;
class Container
{
    public List<string> List { get; private set; }
        = new List<string>();
}
class Program
{
    static void Main()
    {
        var container = new Container();
        var list = container.List;
        Console.WriteLine(list.Count); //0
        container.List.Add("foo");
        Console.WriteLine(list.Count); // 1        
    }
}

这里List<string>Container之外被突变。避免这种情况的一种选项是使用可变数据的只读视图:

using System;
using System.Collections.Generic;
class Container
{
    private readonly List<string> list = new List<string>();
    public IReadOnlyList<string> ListView { get; }
    public Container()
    {
        ListView = list.AsReadOnly();
    }
    public void AddItem(string item)
    {
        list.Add(item);
    }
}
class Program
{
    static void Main()
    {
        var container = new Container();
        Console.WriteLine(container.ListView.Count); //0
        // container.ListView.Add("foo"); // Compile-time error
        container.AddItem("foo");
        Console.WriteLine(container.ListView.Count); // 1        
    }
}

请注意,即使编译时类型为IReadOnlyList<T>,您也不应该直接从属性返回列表,因为那时呼叫者可以将其放回List<T>并进行突变。List<T>.AsReadOnly()返回列表中真正只读的包装器对象,因此呼叫者确实无法将其变异。

最新更新