2009-05-20 54 views
3

我在想在处理集合时使用属性的最佳方式是什么。在处理集合时正确使用属性

例如我有一个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

什么原因可以从外部设置收集? – peterchen 2009-05-20 13:45:44

+0

该属性正在进行自定义控件,该控件允许仅为列表中的Foo对象拖放功能。我打算查询数据库以获取对象列表。每个控件可以有相同或不同的列表。 – Billy 2009-05-20 14:17:48

回答

2

选择

private List<Foo> myOtherList = new List<Foo>(); 

becuse另一只声明了一个参考(其被设置为空),上面的示例声明到列表的引用,创建一个列表和该assignes新列表到参考。

选择

public List<Foo> ListOfFoo 
    { 
    get { return myList; } 
    set { myList= new List<Foo>(value); } 
    } 

当你想myList中为NOT refelect它被分配给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 

的“也”以上是引号,因为实际上,只有一个列表,我的两个第一和第二点,以相同的列表。

0

这取决于。

使用第一种样式时,将创建列表的副本,这通常是不必要的。 .Net约定是为设置者分配对该属性的引用。这就是为什么我会倾向于第二种选择。

但是,如果您打算进行复制操作,第一个选项就是您要查找的内容。

2

一般来说,你不希望使用丰富类型的属性,如List<T>(通常人们会用Collection<T>),一般的集合类型的属性是只读的 - 集合本身能够像Clear方法修改, Add等,这通常是足够的。

例如:

class Foo 
{ 
    Collection<Bar> _bars = new Collection<Bar>(); 

    public Collection<Bar> Bars { get { return _bars; } } 
} 

这也让你打开通过实施Collection<T>后裔和重写InsertItemSetItem等方法来验证修改集合。

0

一般情况下,只露出一个接口(ICollection的,IList的或类似),并使其只读:

private IList<Foo> m_list = new List<Foo>(); 
public IList<Foo> List {get { return m_list; } } 

优点:可以修改的实施,例如从列表切换到可观察列表。您可能需要制作具体类型的m_list成员,而不是界面,例如使用额外的功能。

有了可设置的外部列表,您遇到了一些问题。然而,也有一些情况下,这是需要:

  • 数据可以从外部产生,并且是潜在的大,变化频繁(如几万项)
  • 外部列表之间应共享不同的实例
0

为什么不在类上使用IEnumerator接口,如果您必须使用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) 
    {...} 
    } 
}