为什么要创建从通用列表(.NET)派生的类?

时间:2009-07-17 15:31:41

标签: c# .net generics

区别是:

列表与LT;&的MyType GT; myList中;

myList:List< MyType>

显而易见的是,第一个是列表,第二个是类。但我的问题是第二个优势是什么的优势。

7 个答案:

答案 0 :(得分:8)

后者使您能够拥有一个带有myList的函数,而不仅仅是一个List。这也意味着如果myList的类型发生变化(可能是排序列表),则无需在任何地方更改代码。因此,如果你在任何地方都有List<myType>个对象,那么你不是一直宣称MyList,而是必须改变它们,你就是金色的。

它也是一种语法差异。 myList 是否有列表,或列表?

如果在整个程序中常用它,我会倾向于MyList : List<MyType>

答案 1 :(得分:3)

<强>列表&LT;&的MyType GT; myList 是泛型类型List的一个实例,它可以包含MyType(或从MyType派生的任何类型)的项目

var myTypeInstance = new MyType();
var myList = new List<MyType>;
myList.Add(myTypeInstance);

myList:List&lt; MyType&gt; 是一种新的类型,它继承自List,然后您可以从中创建多个实例:

var myTypeInstance = new MyType();
var myCollectionVariable = new myList();
myCollectionVariable.Add(myTypeInstance);

后者优于前者的主要优点是,如果你想让一些方法作用于List,你可以将它们放在你的类上,而不是将它们存储在“帮助器”或“实用程序”库中,例如:

class myList : List<MyType>
{
  public void DoSomethingToAllMyTypesInList()
  {
    ...
    ...
  }
}

答案 2 :(得分:3)

对象组合link text

VS

类继承link text

答案 3 :(得分:2)

后者是一个继承自基础的新类,但却是截然不同的。最明显的区别是它没有相同的构造函数,但是你也会遇到流式传输问题。

这些是缺点。优点是您可以添加一些自己的方法。即使这样,我也会考虑使用遏制,而不是is-a .-

答案 4 :(得分:2)

我不希望在可能的情况下继承实现。它有它的用途,但如果它不是完全必要的话,那就不值得。

您的问题的主要答案是,通过继承List<T>,您默认将其所有方法设为公开。通常在编写新类时,需要封装。你不想让内部漏出来。例如,假设您想要创建一个线程安全的容器。如果从线程无知容器继承,则客户端将能够使用基类的公共接口来绕过您尝试放入的任何锁定。

另一个流行的错误是当你发现自己经常使用某个特定的容器类型时,尝试使用继承来为它创建一个简短的名称是很诱人的:

class ShortName : Dictionary<string, List<string>> { };

但这不是你所做的 - 你创造了一种全新的类型。这意味着如果您有其他库可以生成正确的数据结构,那么您的代码将无法直接使用它;你必须先将它复制到ShortName。一个例子是Linq,它可以从一个非常易读的函数式表达式轻松构建Dictionary<string, List<string>>,以ToDictionary结尾。

相反,请执行此操作:

using ShortName = Dictionary<string, List<string>>;

现在你有一个简短的snappy别名为unweildy typename,但你实际上仍然使用相同的类型。

答案 5 :(得分:2)

Microsoft设计指南(FxCop和VS代码分析)不建议从List&lt; T&gt;继承公开可见的类。相反,您可以从Collection&lt; T&gt;继承。如this blog post中所述。

但这些指南并不一定与私人集会或内部类相关。

您可能希望从Collection&lt; T&gt;继承的几个原因或列表&lt; T&gt;是:

  • 因此,您可以将自定义应用程序特定成员添加到集合类中。

  • 因此,您可以创建一个ComVisible集合类(不能直接向COM公开通用List,但是您可以公开派生类)。

顺便说一下,命名指南还建议您使用“Collection”后缀命名派生类,即

MyTypeCollection : List<MyType> // or : Collection<MyType>, IList<MyType>

而不是

MyList : List<MyType> // or : Collection<MyType>, IList<MyType>

答案 6 :(得分:1)

有些人发现抽象数据结构远离其应用程序逻辑的好处。如果您认为通用列表不再是表示MyList的最佳数据结构,则可以更改MyList实现,只要您的接口相同,就不必更新任何其他代码。

然而,在许多情况下这都是过度杀戮。

使用抽象数据类型而不是原始数据类型也有语义上的好处,尽管列表类型模糊了这一行。使用字典数据结构时更明显。如果将字典包装在自定义集合类型中,并将键和值公开为属性。您可以编写更像您正在实现的业务逻辑的代码。