在C#泛型之前,每个人都会通过创建实现IEnumerable的集合库来为其业务对象编写集合

IE:

public class CollectionBase : IEnumerable

然后从中派生出他们的Business Object集合。

public class BusinessObjectCollection : CollectionBase

现在使用通用列表类,是否有人只使用它? 我发现我使用了两种技术的妥协:

public class BusinessObjectCollection : List<BusinessObject>

我这样做是因为我喜欢强类型名称而不是仅仅传递列表。

你的方法是什么?

===============>>#1 票数:49 已采纳

我通常只是直接使用List的阵营,除非由于某种原因我需要封装数据结构并提供其功能的有限子集。 这主要是因为如果我没有特定的封装需求,那么这样做只是浪费时间。

但是,使用C#3.0中的聚合初始化功能,我会提倡使用自定义集合类的一些新情况。

基本上,C#3.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}
};

该功能的优点在于它适用于添加任意数量参数的方法。 例如,给定此集合:

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>

===============>>#2 票数:14

建议在公共API中不使用List <T>,而是使用Collection <T>

如果你继承它,你应该没事,afaik。

===============>>#3 票数:9

我更喜欢使用List<BusinessObject> 键入它只是为代码添加了不必要的样板。 List<BusinessObject>是一种特定类型,它不仅仅是任何List对象,因此它仍然是强类型的。

更重要的是,声明List<BusinessObject>会使每个读取代码的人更容易分辨他们正在处理的类型,他们不必搜索以找出BusinessObjectCollection是什么,然后记住它只是一个列表。 通过typedefing,您将不得不要求每个人都必须遵循的一致(重新)命名约定才能使其有意义。

===============>>#4 票数:4

我一直在两个选项上来回走动:

public class BusinessObjectCollection : List<BusinessObject> {}

或者只执行以下操作的方法:

public IEnumerable<BusinessObject> GetBusinessObjects();

第一种方法的好处是您可以更改基础数据存储而不必混淆方法签名。 不幸的是,如果从一个从先前实现中删除方法的集合类型继承,那么您将不得不在整个代码中处理这些情况。

===============>>#5 票数:4

使用List<BusinessObject>类型,您必须在其中声明它们的列表。 但是,在返回BusinessObject列表的地方,请考虑返回IEnumerable<T>IList<T>ReadOnlyCollection<T> - 即返回满足客户端的最弱的合同。

您想要在列表中“添加自定义代码”的位置,列表类型上的代码扩展方法。 再次,将这些方法附加到最弱的合同上,例如

public static int SomeCount(this IEnumerable<BusinessObject> someList)

当然,您不能也不应该使用扩展方法添加状态,因此如果您需要在其后面添加新属性和字段,请使用子类或更好的包装类来存储它。

===============>>#6 票数:3

您应该避免为此目的创建自己的集合。 在重构期间或添加新功能时,想要多次更改数据结构的类型是很常见的。 使用您的方法,您将得到一个单独的类,用于BusinessObjectList,BusinessObjectDictionary,BusinessObjectTree等。

我真的没有看到创建这个类的任何价值,因为classname更具可读性。 是的,尖括号语法有点难看,但它是C ++,C#和Java的标准,所以即使你不编写使用它的代码,你也会一直遇到它。

===============>>#7 票数:2

如果我需要“增值”,我通常只派生自己的集合类。 就像,如果集合本身需要一些标记的“元数据”属性。

===============>>#8 票数:2

我和Jonathan完全一样......只是从List<T>继承。 你可以获得两全其美的效果。 但是我通常只在有一些值要添加时才这样做,比如添加一个LoadAll()方法或者其他什么。

===============>>#9 票数:2

你可以使用两者。 对于懒惰 - 我的意思是生产力 - 列表是一个非常有用的类,它也是“全面的”,并且坦率地充满了YANGNI成员。 再加上MSDN文章提出的合理的论点/建议,已经将List作为公共成员公开,我更喜欢“第三种”方式:

我个人使用装饰器模式只暴露我需要的List,即:

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或更多有利于perf使用Key Value Pair集合或Set 。

===============>>#10 票数:1

我几乎在所有场景中使用通用列表。 我不再考虑使用派生集合的唯一一次是添加特定于集合的成员。 然而,LINQ的出现减少了对此的需求。

===============>>#11 票数:0

我会这样做:

using BusinessObjectCollection = List<BusinessObject>;

这只是创建一个别名而不是一个全新的类型。 我更喜欢直接使用List <BusinessObject>,因为它让我可以在将来的某个时候自由地更改集合的底层结构,而无需更改使用它的代码(只要我提供相同的属性和方法)。

===============>>#12 票数:0

6比1,半打另一个

无论哪种方式都是一样的。 我只有在有理由将自定义代码添加到BusinessObjectCollection时才这样做。

有了它的负载方法返回一个列表允许我在一个通用的泛型类中编写更多的代码,让它只是工作。 比如一个Load方法。

===============>>#13 票数:0

尝试这个:

System.Collections.ObjectModel.Collection<BusinessObject>

它没有必要实现像CollectionBase这样的基本方法

===============>>#14 票数:0

正如其他人所指出的那样,建议不要公开公开List,如果你这样做,FxCop会发牢骚。 这包括继承List,如下所示:

public MyTypeCollection : List<MyType>

在大多数情况下,公共API将根据需要公开IList(或ICollection或IEnumerable)。

如果您需要自己的自定义集合,可以通过继承Collection而不是List来保持FxCop的安静。

===============>>#15 票数:0

如果您选择创建自己的集合类,则应该检查System.Collections.ObjectModel命名空间中的类型。

命名空间定义了基类,使实现者可以更轻松地创建自定义集合。

===============>>#16 票数:0

如果我想屏蔽对实际列表的访问,我倾向于使用我自己的集合。 当你编写业务对象时,你可能需要一个钩子来知道你的对象是否被添加/删除,从这个意义上来说我认为BOCollection是更好的主意。 如果不需要,那么List更轻量级。 如果您需要某种代理(例如,假集合触发来自数据库的延迟加载),您可能还需要使用IList检查以提供其他抽象接口

但是......为什么不考虑Castle ActiveRecord或任何其他成熟的ORM框架? :)

===============>>#17 票数:0

在大多数情况下,我只是采用List方式,因为它在90%的时间内为我提供了所需的所有功能,当需要“额外”的东西时,我继承它,然后编写额外的代码。

===============>>#18 票数:-1

这是方式:

返回数组,接受IEnumerable<T>

=)

  ask by FlySwat translate from so

未解决问题?本站智能推荐:

5回复

如何列出 .IndexOf()对自定义对象执行比较?

我编写了一个帐户对象类,并持有这些帐户对象的静态List<T> 。 我的程序遍历列表中的每个帐户,对该帐户执行一些工作,然后在到达列表末尾时在顶部重置。 我的问题是我的程序完成使用后,需要能够将帐户重新插入列表中,并添加了一些更新的信息。 我可以使用IndexOf()函数按
7回复

.NET列出最佳方法

我有一个列表,在下面声明,在开始时我将列表项默认为{-1, - }。 请注意,在整个计划中,列表大小固定为2。 我的问题是,如果我需要覆盖列表中的两个值,那么最好的方法是什么。 方法1: 方法2: 什么是更好的方法? 使用第二种方法,即使我确定最初设置了2个值
5回复

是否列出 保证插入顺序?

假设我在列表中有3个字符串(例如“ 1”,“ 2”,“ 3”)。 然后,我想对它们进行重新排序以将“ 2”放置在位置1(例如“ 2”,“ 1”,“ 3”)。 我正在使用此代码(将indexToMoveTo设置为1): 这似乎可行,但是我偶尔会得到奇怪的结果。 有时订单不正确
3回复

如何列出 .Contains()查找匹配项目?

我有一个汽车对象列表 我想知道一辆车是否在列表中 包含什么用于确定myCar是否在列表中。 它是否在我的汽车对象上执行“ToString()”。 它是否使用Equals()方法,gethashcode()? 我看到我可以通过我自己的IEqualityComparer来强
5回复

列出从子到父的分配

我想这样做: 我班的完整代码是这样的: 有人可以告诉我为什么这给了我这个错误: 错误2无法将类型'System.Collections.Generic.List'转换为'System.Collections.Generic.List'd:\\ personal \\ d
2回复

IList的 列出

我有一个广泛实现的接口,该接口具有带有特定接口的IList。 而不是大量的文本,请看这里: 基本上,这就是我想要做的。 “触发器”是接口的成员,可以通过几种类型实现。 但是每种类型都需要一个自定义的ITrigger实现和List来解决这个问题(我使用IList似乎很方便)。
4回复

列出数据结构C#效率

目前我正在使用List<short>作为缓冲区来保存一段时间,同时根据缓冲区中的其他值对每个值进行计算。 然后我意识到这可能不是很有效,因为我被告知List<>是一个链表,所以每次我做whatever = myList[100]; 可怜的事情是必须先跳过所有其他节点才
1回复

为什么要列出 继承IEnumerable 和IEnumerable再次

我偶然地看了MSDN上的IList<T>和ICollection<T> ,发现这两个接口的定义是: 注意, ICollection<T>继承自IEnumerable<T>和IEnumerable ,这没关系。 IList<T>
2回复

如何转换字典 列出

我有一个User课程 和Dictionary 现在,我想将Dictionary<string, object> models的值转换为List<User> 。 谁能建议我该怎么做?
2回复

应该列出 。删除前面的List .Exists?

拥有List<string> paths = new List<string>(); 我想删除我不确定的项目。 我应该检查它是否存在或者直接运行Remove方法吗? if (paths.Exists(stringVar))需要或被认为是paths.Remove(