在我的C#项目中,我有一个包含List
的类public class MyClass
{
public MyClass parent;
public List<MyClass> children;
...
}
我想阻止类的用户将一个元素添加(和删除)到children-List,但是他仍然可以解析它的元素。我想在MyClass中处理添加和删除,提供AddChild(MyClass项)和DeleteChild(MyClass项),以确保在将项添加到子列表时,将正确设置该项的父项。
除了实现我自己的IList之外,还知道如何做到这一点吗?
提前致谢, 弗兰克
答案 0 :(得分:29)
如果你给来电者List<T>
,你无法控制这个;你甚至不能继承List<T>
,因为添加/删除不是virtual
。
相反,我会将数据公开为IEnumerable<MyClass>
:
private readonly List<MyClass> children = new List<MyClass>();
public void AddChild(MyClass child) {...}
public void RemoveChild(MyClass child) {...}
public IEnumerable<MyClass> Children {
get {
foreach(var child in children) yield return child;
}
}
(yield return
阻止他们只是投射它)
来电者仍然可以在foreach
上使用.Children
,感谢LINQ,他们也可以做其他所有有趣的事情(Where
,First
等。)< / p>
答案 1 :(得分:14)
除了实施您自己的IList<T>
之外,您还可以返回ReadOnlyCollection<MyClass>
。
public MyClass
{
public MyClass Parent;
private List<MyClass> children;
public ReadOnlyCollection<MyClass> Children
{
get { return children.AsReadOnly(); }
}
}
答案 2 :(得分:6)
将列表公开为IEnumerable<MyClass>
答案 3 :(得分:3)
将列表设为私有,并创建公共方法以从类外部访问其内容。
public class MyClass
{
public MyClass Parent { get; private set; }
private List<MyClass> _children = new List<MyClass>();
public IEnumerable<MyClass> Children
{
get
{
// Using an iterator so that client code can't access the underlying list
foreach(var child in _children)
{
yield return child;
}
}
}
public void AddChild(MyClass child)
{
child.Parent = this;
_children.Add(child);
}
public void RemoveChild(MyClass child)
{
_children.Remove(child);
child.Parent = null;
}
}
顺便说一句,避免声明公共字段,因为你无法控制客户端代码对它们的作用。
答案 4 :(得分:1)
using System.Collections.ObjectModel;
public class MyClass
{
private List<MyClass> children;
public ReadOnlyCollection<MyClass> Children
{
get
{
return new ReadOnlyCollection<MyClass>(children);
}
}
}
答案 5 :(得分:0)
您不需要重新实现IList,只需将List封装在类中,并提供自己的Add和Delete函数,这些函数将负责添加和设置所需的属性。
如果您想通过列表枚举,则可能必须创建自己的枚举器。
答案 6 :(得分:0)
您可以通过将列表设为私有来将列表封装在类中,并将其作为ReadOnlyCollection提供:
public class MyClass {
public MyClass Parent { get; private set; };
private List<MyClass> _children;
public ReadOnlyCollection<MyClass> Children {
get { return _children.AsReadOnly(); }
}
public void AddChild(MyClass item) {
item.Parent = this;
_children.Add(item);
}
public void DeleteChild(MyClass item) {
item.Parent = null;
_children.Remove(item);
}
}
您可以使用私有设置器创建Parent
属性,这样就无法从外部修改它,但AddChild
和DeleteChild
方法可以更改它。 / p>
答案 7 :(得分:0)
使用List(T).AsReadOnly()
。
http://msdn.microsoft.com/en-us/library/e78dcd75.aspx
返回只读IList&lt;(Of&lt;(T&gt;)&gt;) 当前集合的包装器。
自.NET 2.0起可用。