【问题标题】:Why isn't List<T> sealed?为什么 List<T> 不密封?
【发布时间】:2011-01-25 05:20:51
【问题描述】:

看了this问题的答案后想到了这个问题;这基本上表明List&lt;T&gt; 没有虚拟方法,因为它被设计为“快速,不可扩展”。

如果这是设计目标,为什么最初的设计没有包括密封类? (我知道现在这是不可能的,看看这会如何破坏客户端代码中的很多子类)

【问题讨论】:

  • 我猜这是 .NET 中(很多?)糟糕的设计决策之一?
  • 继承List&lt;T&gt; 来创建专门的集合并添加辅助方法(例如List&lt;Crayon&gt;.Count(Color))仍然有用,但@987654325 可能是个好主意@ 一些方法(Add 等)。此外,虽然 .Net 有一些怪癖,但总的来说它是一个一致的框架。此外 - 你不能对所有使用非虚拟方法的非密封类提出相同的问题吗?
  • 我不会把它称为一个糟糕的设计决策——更像是一个非决策。从来没有人说过“嘿,让我们封印这个班级”,所以事实并非如此。有没有害处?
  • @Gabe:嗯,考虑到我使用过的各种企业级代码库,将其密封肯定会让我的生活更轻松......
  • @Kobi:就我个人而言,我会将此类辅助方法放在静态类上,并使其成为针对IList&lt;T&gt;ICollection&lt;T&gt;IEnumerable&lt;T&gt; 的扩展方法。无需派生,然后您可以将此类方法应用于适当元素类型的 any 列表/集合/可枚举,而不仅仅是辅助类的实例。这样的类通常会散发出糟糕设计的味道。

标签: c# .net language-design sealed


【解决方案1】:

没有令人信服的理由来密封它。从中获得它并没有害处。我曾经有相反的心态——只留下你打算让人们从中获得的东西。但事后看来,这没有任何意义。 .NET 的立场是,默认情况下方法是非虚拟的,但默认情况下类是未密封的。 List&lt;T&gt; 只是遵循同样的做法。

当一个类确实覆盖了虚方法但进一步的子类化并不容易或不明显时,你会想要密封一个类。从诸如Dictionary&lt;TKey,TValue&gt; 之类的集合派生以坚持已知类型参数并避免在应用程序中使用它们时将它们键入可能会稍微有用。例如,您可能会有一个派生自 Dictionary&lt;String,String&gt; 的 QueryString 类。

而且由于没有虚拟方法,因此实际上没有什么可以通过密封来保护类。

【讨论】:

  • 两个反驳点:(1)您可以密封覆盖的成员,因此密封覆盖方法的派生类并不是绝对必要的——只需密封您覆盖的方法,也可能覆盖您没有覆盖的任何方法'只是这样你就可以密封它们。 (2) 鉴于您认为密封类实际上并不需要的一种情况,您会得出结论,密封类属性没有价值吗?
  • 我不会说它没有任何价值,但在很多情况下它会被不必要地使用。但是话虽如此,虽然你可以密封方法,但你不能在不密封类的情况下“密封”构造函数。此外,sealed 关键字是一个很好的强制声明,您不打算从该类派生。
  • 好吧,构造函数不能被覆盖,所以密封它们没有任何意义。此外,我无法协调您最近的声明 “sealed 关键字是一个很好的强制声明,您不打算从该类派生” 与您的答案中的这个声明:“我曾经有相反的心态——只留下你打算让人们从中获得的东西。但事后看来,这没有任何意义。”
  • 我不确定你的意思。我所说的只是我以前“默认密封”,现在我不再这样做了。正如我所说,在某些情况下,我仍想阻止派生,例如在 Prism 模块的情况下。但就List&lt;T&gt;(和其他通用集合)而言,我对 BCL 团队做出的决定没有任何问题。
  • 好的,我只是想澄清一下您的回答,因为我的初步印象显然与您的预期不同。
【解决方案2】:

他们决定不将List&lt;T&gt; 密封肯定有很多原因,但是,一种可能是框架设计团队希望与ArrayList(未密封)对等,以便现有程序和具有设计的框架基于扩展ArrayList 将能够更轻松地升级他们的设计以使用List&lt;T&gt;。将List&lt;T&gt; 密封对于这些用途来说将是一个真正的死胡同,而强有力的指导设计选择之一就是允许人们轻松地将他们现有的代码库从ArrayList 升级到List&lt;T&gt;

【讨论】:

  • 没有理由他们必须真正决定不密封List&lt;T&gt;,因为未密封是默认设置。他们所要做的就是决定。此外,他们将Collection&lt;T&gt; 设计为派生自,以便它可以取代ArrayList
  • @Gabe 不完全是。即使他们想要密封List&lt;T&gt;,他们也可能会对依赖扩展ArrayList 的用户\框架开发人员造成困扰。这是他们必须在决策中包含的内容。我听说你是。 Collection&lt;T&gt; 这很有趣。虽然您可以通过继承和扩展将行为添加到 List&lt;T&gt;,但您无法正确覆盖行为。你是对的,Collection&lt;T&gt; 更适合覆盖行为。我更多地指的是扩展行为。不过你说得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 2019-07-02
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多