简体   繁体   English

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

[英].NET C# Array Instantiation/Passing Theory

I have a special object which holds a list of objects and a bunch of accompanying properties for the list. 我有一个特殊的对象,其中包含一个对象列表和该列表的许多附带属性。

I have a function which injects items into the List portion of my special object. 我有一个将项目注入到我的特殊对象的列表部分中的功能。 The function depends on properties that accompany the list, so I opted to create a new object which holds both properties and the List. 该函数取决于列表附带的属性,因此我选择创建一个同时包含属性和列表的新对象。

Question 1: Who is responsible for ensuring the List isn't null before the function begins injecting items? 问题1:在函数开始注入项目之前,谁负责确保List不为空?

  1. Should the caller create a new list and pass it to the function? 调用者是否应该创建一个新列表并将其传递给函数?

  2. Should the callee create a new list and assign it to the object regardless of the state of the object passed in? 被调用者是否应该创建一个新列表并将其分配给该对象,而不管传入对象的状态如何?

  3. Should the function be designed to take in the object and return a new list WITHOUT modifying the object, leaving it to the caller to assign the returned list to its special object? 该函数是否应该设计成可以接受该对象并返回一个新列表,而无需修改该对象,而是将其留给调用者以将返回的列表分配给它的特殊对象?

or... are there other options I haven't considered? 还是...还有其他我没有考虑的选择?

Related Question 2: Given that my design requires properties that accompany a List, should I have chosen to create a new class which holds both properties and a List, or should I create created a sub-class of List that holds additional properties? 相关问题2:鉴于我的设计需要List附带的属性,我应该选择创建一个同时包含属性和List的新类,还是应该创建一个创建List的子类来保存其他属性?

In short, the object containing the list is responsible, conceptually, for having a valid means to store data, meaning it should be responsible for instantiating its list when one is needed. 简而言之,从概念上讲,包含列表的对象负责使用一种有效的方式来存储数据,这意味着它应该在需要时负责实例化其列表。

If the object is designed to represent a collection of objects, then it is responsible for maintenance of whatever it actually uses internally to store them, unless part of the objective is for the new object to be a "wrapper" for multiple types of collection, allowing for behavior customization based on the type of collection used internally. 如果对象设计为表示对象的集合,则它负责维护内部实际用于存储对象的任何内容,除非目标的一部分是使新对象成为多种类型的集合的“包装器”,允许根据内部使用的集合类型自定义行为。

Consider a List. 考虑一个列表。 It uses an array internally to store data, and deals with the resizing of said array to store new objects as may be required. 它在内部使用一个数组来存储数据,并处理所述数组的大小以存储可能需要的新对象。 You don't have to know that about a List; 您不必了解列表。 conceptually, it is an ordered, indexed collection allowing insertion and removal of elements. 从概念上讲,它是一个有序的,索引编制的集合,允许插入和删除元素。 It could have been implemented with a linked list, or a red-black tree, or whatever; 它可以用链表,红黑树或其他任何东西来实现。 those would have had performance and complexity implications. 这些将对性能和复杂性产生影响。

Back to the case in point. 回到正题。 Your object, meant to be a List with additional properties, should hide its internal data structure. 您的对象应该是具有其他属性的List,应该隐藏其内部数据结构。 Users shouldn't need to know there's a List in there holding elements. 用户不需要知道那里的元素列表。 That means your object should know how to instantiate its own internal data structure, and expose methods that would be used by the caller to inject new elements, which act on the internal list. 这意味着您的对象应该知道如何实例化其自己的内部数据结构,并公开调用者将用来注入新元素的方法,这些元素将作用于内部列表。

The one exception is that of a "wrapper" which adds new functionality which could apply to any of a subset of other classes, and it is important to allow the user to specify which class the new one should "wrap" in a particular usage. 一个例外是“包装器”的例外,该包装器增加了可应用于其他类的子集中任何一个的新功能,并且重要的是允许用户指定在特定用法中应将新类“包装”到哪个类。 An example is a BlockingCollection. 一个示例是BlockingCollection。 It adds the ability to block a thread that is performing some concurrent operation on the collection until it is valid and safe to perform said operation (for instance, a thread attempting to get an item from the BlockingCollection will be blocked if the collection is empty, until another thread adds something). 它增加了阻止对集合执行并发操作的线程的能力,直到它有效且安全地执行该操作为止(例如,如果集合为空,则尝试从BlockingCollection获取项目的线程将被阻止,直到另一个线程添加了一些东西)。 When created, you can specify that the BlockingCollection uses a specific implementation of the IProducerConsumerCollection interface; 创建后,您可以指定BlockingCollection使用IProducerConsumerCollection接口的特定实现。 most likely that will be one of the built-in "Concurrent" collections in the same namespace, such as ConcurrentBag, ConcurrentQueue or ConcurrentDictionary. 很有可能是同一名称空间中的内置“并发”集合之一,例如ConcurrentBag,ConcurrentQueue或ConcurrentDictionary。 Even in this case, there is a "default" option; 即使在这种情况下,也有一个“默认”选项。 you can instantiate a BlockingCollection object without specifying the internal Concurrent structure to use, and the object will default to a ConcurrentQueue. 您可以实例化BlockingCollection对象,而无需指定要使用的内部Concurrent结构,并且该对象将默认为ConcurrentQueue。

Assuming your list is a field/member of the instance of your class, I would recommend new ing up the list in the class's constructor. 假设你的列表您的类的实例的领域/成员,我会建议new ING在类的构造函数列表。

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

Or accomplishing the same thing without the constructor: 或者在没有构造函数的情况下完成同样的事情:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM