.NET C#数组实例化/传递理论

时间:2012-04-20 18:08:52

标签: c# .net arrays theory

我有一个特殊的对象,它包含一个对象列表和一堆附带的列表属性。

我有一个函数可以将项目注入我的特殊对象的List部分。该函数依赖于列表附带的属性,因此我选择创建一个包含属性和List的新对象。

问题1:在函数开始注入项目之前,谁负责确保List不为null?

  1. 调用者是否应该创建新列表并将其传递给函数?

  2. 被调用者是否应创建新列表并将其分配给对象,而不管传入的对象的状态如何?

  3. 该函数是否应设计为接收对象并返回新列表而不修改对象,将其留给调用者以将返回的列表分配给其特殊对象?

  4. 或......还有其他我未考虑的选择吗?

    相关问题2:鉴于我的设计需要伴随List的属性,我是否应该选择创建一个同时包含属性和List的新类,或者我应该创建一个包含其他属性的List子类?

2 个答案:

答案 0 :(得分:3)

简而言之,包含列表的对象在概念上负责拥有存储数据的有效方法,这意味着它应该负责在需要时实例化其列表。

如果对象被设计为表示对象的集合,那么它负责维护它在内部实际用于存储它们的任何内容,除非目标的一部分是新对象是多个类型的“包装器”集合,允许基于内部使用的集合类型进行行为自定义。

考虑一个列表。它在内部使用数组来存储数据,并处理所述数组的大小调整以存储可能需要的新对象。你不必了解List;从概念上讲,它是一个有序的索引集合,允许插入和删除元素。它本来可以用链表,红黑树等实现;那些会产生性能和复杂性。

回到案例。您的对象(具有附加属性的List)应隐藏其内部数据结构。用户不应该知道那里有持有元素的List。这意味着您的对象应该知道如何实例化其自己的内部数据结构,并公开调用者将用于注入新元素的方法,这些元素作用于内部列表。

一个例外是“包装器”,它增加了可以应用于其他类的任何子集的新功能,并且允许用户指定新的应该“包装”在哪个类中是很重要的。特殊用途。一个例子是BlockingCollection。它增加了阻塞正在对集合执行某些并发操作的线程的能力,直到它有效且安全地执行所述操作(例如,如果集合为空,将阻止尝试从BlockingCollection获取项目的线程,直到另一个线程添加东西)。创建时,您可以指定BlockingCollection使用IProducerConsumerCollection接口的特定实现;很可能是同一命名空间中内置的“Concurrent”集合之一,例如ConcurrentBag,ConcurrentQueue或ConcurrentDictionary。即使在这种情况下,也有一个“默认”选项;您可以在不指定要使用的内部Concurrent结构的情况下实例化BlockingCollection对象,该对象将默认为ConcurrentQueue。

答案 1 :(得分:2)

假设您的列表是您的类实例的字段/成员,我建议new在类的构造函数中列出该列表。

public class SpecialObject
{
    List<something> myList;
    public SpecialObject()
    {
        myList = new List<something>();
    }
}

或者在没有构造函数的情况下完成同样的事情:

public class SpecialObject
{
    List<something> myList = new List<something>();
}