List <BusinessObject>还是BusinessObjectCollection?
在Cgenerics之前,每个人都将通过创建实现IEnumerable的集合库来为其业务对象编码集合
IE:
public class CollectionBase : IEnumerable
然后从中派生其业务对象集合。
public class BusinessObjectCollection : CollectionBase
现在有了通用列表类,是否有人会使用它呢?我发现我使用了两种技术的折衷方案:
public class BusinessObjectCollection : List<BusinessObject>
之所以这样做,是因为我喜欢使用强类型的名称,而不仅仅是传递列表。
你的方法是什么?
解决方案
回答
通常,只有在需要"增加价值"时,我才派生自己的收藏类。就像,如果集合本身需要带有一些"元数据"属性标记。
回答
我一直在来回选择2个选项:
public class BusinessObjectCollection : List<BusinessObject> {}
或者仅执行以下操作的方法:
public IEnumerable<BusinessObject> GetBusinessObjects();
第一种方法的好处是我们可以更改基础数据存储,而不必弄乱方法签名。不幸的是,如果我们继承的集合类型从以前的实现中删除了一个方法,那么我们将不得不在整个代码中处理这些情况。
回答
我和我们乔纳森(Jonathan)完全一样...只是从List <T>
继承而来。我们将两全其美。但是我通常只在有一些值要添加时才这样做,例如添加LoadAll()
方法或者其他方法。
回答
1个中的6个,另外六个
无论哪种方式都是一样的。仅当我有理由将自定义代码添加到BusinessObjectCollection中时,才执行此操作。
有了它,就没有了使用load方法返回的列表,这使我可以在一个通用的泛型类中编写更多代码并使其工作。如Load方法。
回答
我更喜欢只使用List <BusinessObject>
。类型化它只是在代码中添加了不必要的样板。 List <BusinessObject>是一种特定的类型,它不仅是任何List对象,因此仍具有强类型。
更重要的是,声明List <BusinessObject>
可以使每个阅读代码的人都更轻松地知道他们正在处理的类型,他们不必搜索以找出BusinessObjectCollection
是什么,然后记住只是一个清单。通过类型定义,我们必须要求每个人都必须遵循一个一致的(重新)命名约定才能使之有意义。
回答
我们可能应该避免为此目的创建自己的集合。在重构期间或者添加新功能时,几次更改数据结构的类型是很常见的。使用方法,我们将获得一个单独的类,用于BusinessObjectList,BusinessObjectDictionary,BusinessObjectTree等。
我仅仅在创建类时并没有看到任何价值,只是因为类名更具可读性。是的,尖括号语法有点丑陋,但这是C ++和Cand Java中的标准语法,因此即使我们不编写使用它的代码,也总是会遇到这种情况。
回答
建议在公共API中不要使用List <T>,而要使用Collection <T>
如果我们从它继承,那么我们应该没问题,afaik。
回答
通常,我通常只是直接使用List,除非出于某种原因我需要封装数据结构并提供其功能的有限子集。这主要是因为如果我对封装没有特别的要求,那么这样做只会浪费时间。
但是,借助C3.0中的聚合初始化功能,在某些新情况下,我会提倡使用定制的收集类。
基本上,C3.0允许任何实现" IEnumerable"并具有Add方法的类使用新的聚合初始化程序语法。例如,由于Dictionary定义了方法Add(K key,V value),因此可以使用以下语法初始化字典:
var d = new Dictionary<string, int> { {"hello", 0}, {"the answer to life the universe and everything is:", 42} };
该功能的优点在于,它可用于带有任意数量参数的add方法。例如,给定此集合:
class c1 : IEnumerable { void Add(int x1, int x2, int x3) { //... } //... }
可以像这样初始化它:
var x = new c1 { {1,2,3}, {4,5,6} }
如果我们需要创建复杂对象的静态表,这将非常有用。例如,如果我们只使用List <Customer>
,并且想创建一个客户对象的静态列表,则必须像这样创建它:
var x = new List<Customer> { new Customer("Scott Wisniewski", "555-555-5555", "Seattle", "WA"), new Customer("John Doe", "555-555-1234", "Los Angeles", "CA"), new Customer("Michael Scott", "555-555-8769", "Scranton PA"), new Customer("Ali G", "", "Staines", "UK") }
但是,如果我们使用自定义集合,例如:
class CustomerList : List<Customer> { public void Add(string name, string phoneNumber, string city, string stateOrCountry) { Add(new Customer(name, phoneNumber, city, stateOrCounter)); } }
然后,我们可以使用以下语法初始化集合:
var customers = new CustomerList { {"Scott Wisniewski", "555-555-5555", "Seattle", "WA"}, {"John Doe", "555-555-1234", "Los Angeles", "CA"}, {"Michael Scott", "555-555-8769", "Scranton PA"}, {"Ali G", "", "Staines", "UK"} }
这具有易于键入和易于阅读的优点,因为它们不需要为每个元素重新键入元素类型名称。如果元素类型很长或者很复杂,则此优势可能会特别强大。
话虽如此,这仅在我们需要在应用程序中定义的静态数据收集时有用。某些类型的应用程序(例如编译器)一直在使用它们。诸如典型的数据库应用程序之类的其他应用程序则不是,因为它们从数据库加载了所有数据。
我的建议是,如果我们需要定义对象的静态集合,或者需要封装掉集合接口,然后创建一个自定义集合类。否则,我将直接使用List <T>
。
回答
我几乎在所有情况下都使用通用列表。我唯一会考虑使用派生集合的时间是,如果我添加集合特定成员。但是,LINQ的出现减少了对此的需求。
回答
这是这样的:
返回数组,接受IEnumerable <T>
=)
回答
正如其他人指出的那样,建议不要公开公开List,如果这样做,FxCop会发牢骚。这包括从List继承,如:
public MyTypeCollection : List<MyType>
在大多数情况下,公共API会适当地公开IList(或者ICollection或者IEnumerable)。
如果我们想要自己的自定义集合,则可以通过从Collection继承而不是List来使FxCop保持安静。
回答
如果选择创建自己的集合类,则应在System.Collections.ObjectModel命名空间中检出类型。
命名空间定义了基础类,使实现者可以更轻松地创建自定义集合。
回答
如果我想屏蔽对实际列表的访问,则倾向于使用自己的收藏集来进行。在编写业务对象时,很有可能需要一个钩子才能知道是否要添加/删除对象,从这种意义上讲,我认为BOCollection是更好的主意。如果不需要,那么List更轻巧。另外,如果我们需要某种代理(例如,虚假集合会触发数据库的延迟加载),则可能需要检查使用IList来提供其他抽象接口。
但是...为什么不考虑Castle ActiveRecord或者任何其他成熟的ORM框架? :)
回答
在大多数情况下,我只是简单地使用List方法,因为它为我提供了90%的时间所需的所有功能,并且当需要"多余"的东西时,我会从中继承并编码更多的东西。
回答
我会这样做:
using BusinessObjectCollection = List<BusinessObject>;
这只会创建一个别名,而不是一个全新的类型。我更喜欢直接使用List <BusinessObject>,因为它使我可以在将来的某个时候自由更改集合的基础结构,而无需更改使用它的代码(只要我提供相同的属性和方法)。
回答
试试这个:
System.Collections.ObjectModel.Collection<BusinessObject>
它不需要像CollectionBase这样的基本方法
回答
我们可以同时使用。对于懒惰,我的意思是生产率列表是一个非常有用的类,它也是"综合性的",并且坦率地说是由YANGNI成员组成的。再加上已经链接有关将List公开为公众成员的MSDN文章提出的明智的论点/建议,我更喜欢"第三种"方式:
就个人而言,我使用装饰器模式仅显示列表中需要的内容,即:
public OrderItemCollection : IEnumerable<OrderItem> { private readonly List<OrderItem> _orderItems = new List<OrderItem>(); void Add(OrderItem item) { _orderItems.Add(item) } //implement only the list members, which are required from your domain. //ie. sum items, calculate weight etc... private IEnumerator<string> Enumerator() { return _orderItems.GetEnumerator(); } public IEnumerator<string> GetEnumerator() { return Enumerator(); } }
更进一步,我可能会将OrderItemCollection抽象到IOrderItemCollection中,以便将来在以后交换我的IOrderItemCollection实现(我可能更喜欢使用其他内部可枚举的对象,例如Collection或者更多的likley来使性能使用键值对集合或者Set 。
回答
使用`List <BusinessObject>'类型,在其中必须声明它们的列表。然而,
如果要返回" BusinessObject"的列表,请考虑返回" IEnumerable <T>"," IList <T>"或者" ReadOnlyCollection <T>",即返回满足客户要求的最弱合同。
要在列表中"添加自定义代码"的地方,列表类型上的代码扩展方法。同样,将这些方法添加到最弱的合约上,例如
public static int SomeCount(this IEnumerable<BusinessObject> someList)
当然,我们不能也不应使用扩展方法添加状态,因此,如果我们需要在其后添加新属性和字段,请使用子类或者更好的包装类来存储此属性。