【问题标题】:'Don't expose generic list', why to use collection<T> instead of list<T> in method parameter'不要公开通用列表',为什么在方法参数中使用 collection<T> 而不是 list<T>
【发布时间】:2013-05-24 07:03:36
【问题描述】:

我正在使用 FxCop,它显示“不要公开通用列表”的警告,建议使用 Collection&lt;T&gt; 而不是 List&lt;T&gt;。首选它的原因,我知道所有这些东西,如this SO postMSDN 以及我读过的更多文章中所述。

但我的问题是,我很少有方法可以进行如此繁重的计算,并且方法接受 List&lt;T&gt; 的参数,这在性能方面应该更快更好。但 FxCop 也为此发出警告。所以一种选择是我应该将参数声明为Collection&lt;T&gt;,然后在方法内部使用ToList(),然后使用它。

那么优化了哪一个?

“抑制这种情况的警告”“在参数中使用Collection&lt;T&gt;,然后在方法本身中使用ToList()”。

【问题讨论】:

  • IList 有什么问题?
  • IList 没有提供 AddRange() & sort 之类的方法
  • 如果您需要速度,您可以使用List&lt;&gt;,只要您不希望调用者知道集合的元素何时更改。我们有很多对速度至关重要的计算(对大量 ECG 数据进行分析),这些计算速度太慢了,因此我们在某些情况下使用 List&lt;&gt; 甚至普通数组。我想我是说我认为List&lt;&gt; 适合数字。我说的是List&lt;double&gt;List&lt;int&gt;,即原语列表。
  • 你确定,当使用Collection&lt;T&gt;而不是List&lt;T&gt;时,你真的会有性能滞后吗?我的意思是,在你的特殊情况下?另外,为什么不使用SuppressMessageAttribute,如果你真的知道,你在做什么?
  • 要求“更好”的选项会导致主观回答。您能否重新措辞或澄清一下,以便我们提供客观答案?

标签: c# generics collections


【解决方案1】:

已编写代码分析/FxCop 规则以支持框架创建者(Microsoft 创建了很多框架)。框架由外部各方使用,在设计公共接口时应该小心。如果您没有编写供外部各方使用的框架,您可以简单地忽略不为您提供价值的规则。

但是,存在此规则的原因之一是在类上公开集合有些困难。集合中的元素通常由包含类拥有,在这种情况下,如果您允许客户端修改用于存储聚合项的集合,则会违反封装。通过返回List&lt;T&gt;,您允许客户端以多种不同的方式修改集合。但通常您希望跟踪集合中的项目。例如。添加一个新元素可能需要在包含类等中进行一些额外的簿记。当您返回 List&lt;T&gt; 时,您会失去这种控制,除非您在返回它时制作一个副本(但是客户应该明白他们只会得到集合和修改的副本将被忽略)。

总而言之,您可以通过避免暴露 List&lt;T&gt; 之类的类以及更明确地说明如何添加、修改和删除聚合元素来改进您的类设计。但是,如果您赶时间并且只想编写一些代码,那么使用List&lt;T&gt; 可能正是您完成工作所需要的。

【讨论】:

    【解决方案2】:

    只要您不编写其他人希望在不久的将来扩展的框架,就不必费心在公共属性中使用通用列表。 我建议压制警告。如果需求发生变化,您可以稍后重构您的类。

    【讨论】:

      【解决方案3】:

      恕我直言,您对“不要公开通用列表”的解释,它建议使用集合而不是列表。是无效的。

      collection 和 list 的关键区别在于 list 中的元素是有序的。某些方法可能要求传递的元素具有顺序。然后我们必须在参数中使用一个列表。

      理解传递警告的关键是您应该使用接口IList&lt;T&gt; 而不是具体类List&lt;T&gt;

      由于该方法对列表进行操作,因此它是哪种列表并不重要。关键因素是它是一个列表。

      结束方法参数应尽可能抽象。

      【讨论】:

        【解决方案4】:

        您应该使用最适合您的目的的类型(并在适当的情况下禁止显示警告)。如果您要传递一堆项目,并且顺序和唯一性无关紧要,请使用集合。如果您要传递有序的项目集合,请使用列表。如果您传递的数据使得每个项目都是唯一的,但顺序无关紧要,请使用集合。使用具有适合交换的语义的类型。在少数情况下,您需要的语义和方法不一定对齐(假设您需要 AddRange),请例外处理,或使用转换方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-16
          • 2017-08-17
          • 2010-10-22
          • 1970-01-01
          相关资源
          最近更新 更多