我想知道在处理集合时使用属性的最佳方法是什么。
例如,我有一个类Foo,我希望存储该类的列表。应使用以下哪一项:
private List<Foo> myList;
private List<Foo> myOtherList = new List<Foo>();
现在为该物业:
public List<Foo> ListOfFoo
{
get
{
return myList;
}
set
{
myList= new List<Foo>(value);
}
}
或者该集应该是值吗?
public List<Foo> ListOfFoo
{
get
{
return myList;
}
set
{
myList= value;
}
}
答案 0 :(得分:2)
通常,您不希望使用类似List<T>
的富类型的属性(通常会使用Collection<T>
),并且通常集合类型的属性是只读的 - 集合本身可以可以使用Clear
,Add
等方法进行修改,这通常就足够了。
例如:
class Foo
{
Collection<Bar> _bars = new Collection<Bar>();
public Collection<Bar> Bars { get { return _bars; } }
}
这也让您可以通过实现Collection<T>
的后代并覆盖InsertItem
,SetItem
等方法来验证对集合的修改。
答案 1 :(得分:2)
选择
private List<Foo> myOtherList = new List<Foo>();
然后另一个只声明一个引用(设置为null),上面的示例声明了对列表的引用,创建了一个列表并将该新列表分配给引用。
选择
public List<Foo> ListOfFoo
{
get { return myList; }
set { myList= new List<Foo>(value); }
}
当您希望myList在重新分配给myList后发生在列表中的任何更改时,例如
List<string> myFirstList = new List<string>();
myFirstList.Add("Hello");
myFirstList.Add("World");
List<string> mySecondList = new List<string>(myFirstList);
// mySecondList now contains Hello & world
myFirstList.Add("Boyo");
// myFrist List now contains Hello, world & Boyo
// mySecondList still contains Hello & world
选择
public List<Foo> ListOfFoo
{
get { return myList; }
set { myList= value; }
}
当您希望两个引用都指向同一个对象时,例如
List<string> myFirstList = new List<string>();
myFirstList.Add("Hello");
myFirstList.Add("World");
List<string> mySecondList = myFirstList;
// mySecondList now contains Hello & world
myFirstList.Add("Boyo");
// myFrist List now contains Hello, world & Boyo
// mySecondList "also" contains Hello, world & Boyo
上面的“也”是引号,因为实际上只有一个列表,我的第一个和第二个列表都指向同一个列表。
答案 2 :(得分:0)
取决于。
使用第一个样式时,您可以创建列表的副本,这通常是不必要的。 .Net约定用于setter分配对属性的引用。这就是我倾向于第二种选择的原因。
但是,如果您打算进行复制操作,则第一个选项就是您要查找的内容。
答案 3 :(得分:0)
通常,只公开一个接口(ICollection,IList或类似的接口),并使其只读:
private IList<Foo> m_list = new List<Foo>();
public IList<Foo> List {get { return m_list; } }
优势:您可以修改实施,例如从列表切换到可观察列表。您可能需要创建具体类型的m_list
成员而不是接口,例如使用额外的功能。
使用可设置的外部列表,您会遇到一些问题。但是,在某些情况下需要这样做:
答案 4 :(得分:0)
为什么不在类上使用IEnumerator-Interface,如果必须使用setter,请使用某种方法。
这样你也隐藏了实际的List-Implementation。
class FooBar : IEnumerator
{
private Collection<Foo> col;
public IEnumarator GetEnumerator()
{
return col.GetEnumerator();
}
public void SetList(Collection col)
{
this.col= col; // you can also make this more general and convert the parameter so it fits your listimpl.
}
}
class Clazz
{
private void WhatEver(){
FooBar foobar = new FooBar();
...
foreach(Foo f in foobar)
{...}
}
}