使用公共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()
返回列表中真正只读的包装器对象,因此呼叫者确实无法将其变异。