考虑一下这个C#程序:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SandboxApplication
{
public class IntsOwner
{
private List<int> _ints;
public IntsOwner (IEnumerable<int> ints)
{
_ints = ints.OrderBy(i => i).ToList(); // They must be in the correct order
}
public IEnumerable<int> Ints
=> _ints;
public void CheckFirstTwoInts ()
{
if (_ints.Count < 2)
{
Console.WriteLine("You need to collect some more ints before trying this.");
}
else if (_ints[0] <= _ints[1])
{
Console.WriteLine("Your ints are in the correct order and you should stop worrying.");
}
else
{
Console.WriteLine("You've failed, your highness.");
}
}
}
class Program
{
static void Main (string[] args)
{
var intsOwner = new IntsOwner(new List<int> {1, 2, 3, 4, 5});
var ienumerable = intsOwner.Ints;
var list = (List<int>)ienumerable;
intsOwner.CheckFirstTwoInts();
list[0] = 6;
intsOwner.CheckFirstTwoInts();
Console.ReadLine();
}
}
}
如果你运行它,你会得到两行输出:
Your ints are in the correct order and you should stop worrying.
You've failed, your highness.
IntsOwner
类的原始设计者希望确保为私有成员_ints
保留特定属性(列表元素的排序)。但是因为通过Ints
属性返回对实际对象的引用,所以该类的用户可以修改该对象,以便该属性不再成立。
这种代码在实践中似乎不太可能,但仍然令人不安的是,对私有成员的控制可能会以这种方式“泄漏”。如果有的话,程序员应该试图阻止这种事情多少呢?例如,将Ints
属性的表达式主体更改为_ints.Select(i = i)
从而关闭这种修改私有成员的方式是合理的还是相称的?或者这对于代码的可读性会不会有不必要的偏执?
答案 0 :(得分:2)
我总是在ToList
之后添加对AsReadOnly()的调用不变性是关键,而不仅仅是返回类型中知识最少的原则
https://msdn.microsoft.com/en-us/library/e78dcd75(v=vs.110).aspx
答案 1 :(得分:-3)
您可以执行类似
的操作public IEnumerable<int> Ints => _ints.ToList<int>();
因此您不会返回对_ints的引用,而只返回复制列表。任何修改返回值的人都只会修改自己的副本,而不是私有存储的副本。