列表<T>只读私有集

Jon*_*Jon 50 .net c# generics c#-3.0

我怎样才能公开一个List<T>只读它,但可以私下设置?

这不起作用:

public List<string> myList {readonly get; private set; }
Run Code Online (Sandbox Code Playgroud)

即使你这样做:

public List<string> myList {get; private set; }
Run Code Online (Sandbox Code Playgroud)

你仍然可以这样做:

myList.Add("TEST"); //This should not be allowed
Run Code Online (Sandbox Code Playgroud)

我想你可以:

public List<string> myList {get{ return otherList;}}
private List<string> otherList {get;set;}
Run Code Online (Sandbox Code Playgroud)

Phi*_*eck 96

我认为你正在混合概念.

public List<string> myList {get; private set;}
Run Code Online (Sandbox Code Playgroud)

已经 "只读"了.也就是说,在这个类之外,没有任何东西可以设置myList为不同的实例List<string>

但是,如果您想要一个只读列表,如"我不希望人们能够修改列表内容 ",那么您需要公开一个ReadOnlyCollection<string>.你可以这样做:

private List<string> actualList = new List<string>();
public ReadOnlyCollection<string> myList
{
  get{ return actualList.AsReadOnly();}
}
Run Code Online (Sandbox Code Playgroud)

请注意,在第一个代码段中,其他人可以操作List,但无法更改您拥有的列表.在第二个片段中,其他人将获得一个他们无法修改的只读列表.

  • 更好的是将ReadOnlyCollection作为IList <string>. (4认同)
  • 好极了.很多人都错过了引用类型的概念并将引用设置为readonly.+1 (3认同)

Dar*_*rov 11

如果您想要只读集合使用ReadOnlyCollection<T>,而不是List<T>:

public ReadOnlyCollection<string> MyList { get; private set; }
Run Code Online (Sandbox Code Playgroud)


Ser*_*kiy 11

我更喜欢使用IEnumerable

private readonly List<string> _list = new List<string>();

public IEnumerable<string> Values // Adding is not allowed - only iteration
{
   get { return _list; }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的方法,除了它有缺陷:MyClass m = new MyClass(); List <string> x = m.Values as List <string>; x.Add( "测试"); foreach(字符串在m.Values中){Console.WriteLine(s); } //这允许我只通过强制转换为它添加值. (10认同)
  • 1)尝试将接口强制转换为某个类 - 接口的使用不正确,你应该踢一个这样做的人2)yield语句有什么问题? (7认同)
  • 好吧,那就是黑客:)你也可以使用反射向内部集合中添加元素.IEnumerable隐藏了MyClass客户端的实现.你能确定我没有在里面使用LinkedList吗? (5认同)
  • 你总是可以反思找到集合类型,所以我总是很有把握.如果你要这样做,那就做吧.当然,任何人都可以使用反射来"破解"对象来添加项目,但是你无能为力.您可以做的就是练习适当的技术并使用框架. (3认同)
  • 如果API提供ICollection <T>,则从ICollection <T>转换为List <T>是一种破解. (3认同)
  • 如果要公开IEnumerable <string>,您仍应将其实现为_list.AsReadOnly(),以防止DustinDavis描述的问题.但是我更喜欢将结果作为IList <string>(或者可能是ICollection <string>)返回,因为这会告诉用户该属性不会使用惰性求值(yield语句). (2认同)
  • @DustinDavis,如何使用反射设置更改内部集合更多的黑客而不是转换为类型**NOT**由API提供来修改它? (2认同)
  • 您没有正确地将类型公开给您的消费者.将它公开为IEnumerable并不会告诉他们这是一个ReadOnlyCollection.如果转换为另一种类型是黑客,那么你说从ICollection <>到List <>是一个黑客.它与IEnumerable <>到List <>有何不同?事实并非如此. (2认同)

Sea*_*ean 10

返回一个ReadOnlyCollection,它实现了IList <>

private List<string> myList;

public IList<string> MyList
{
  get{return myList.AsReadOnly();}
}
Run Code Online (Sandbox Code Playgroud)