Visual Studio代码分析规则 - “不公开通用列表”

时间:2010-06-15 14:32:56

标签: c# linq extension-methods code-analysis fxcop

Do not expose generic lists

如果我的所有方法都需要公开一个集合,那么我需要使用Linq扩展.ToList(),几乎我需要在所有代码中使用列表或用户集合。

如果是这种情况,。ToList()会忽略规则吗?或者是否有一种技术,比如复制列表以修复违规行为并仍返回列表?

3 个答案:

答案 0 :(得分:8)

我禁用该规则,因为我觉得它不是有效的规则。如果要返回包含O(1)计数且不是对内部字段的直接引用的集合,List<T>是最佳选择。

我不太了解你的情况,但听起来你有一个方法可以通过某些内部数据返回LINQ查询。如果是这种情况,那么在数据上使用.ToList()是合适的,因为您可能不希望将来修改内部字段以影响方法的返回值。在这种情况下,没有理由不将其公开为List<T>

答案 1 :(得分:8)

此规则确实很嘈杂,但有一些非常有效的理由可以避免库代码中的List<T>。这一切都取决于具体情况。在禁用规则或抑制给定事件之前,需要考虑以下几点:

  • List<T>通常是输入参数的不良选择,因为它会强制调用者不必要地复制数据。我已经看到很多代码在List<T>足够时将参数声明为T[]IEnumerable<T>

  • List<T>也可能是物业的不良选择。考虑以下备选方案:

    public class Course {
        public List<Course> Prerequisites { get; }
    }
    public class Course {
        public Collection<Course> Prerequisites { get; }
    }
    

    目的是调用者可以通过修改集合来改变课程的先决条件。在这种情况下,如果我们使用List<Course>,则由于Course未提供任何修改回调,因此在先决条件发生变化时无法通知List<T>类。因此,在此上下文中使用List<T>就像拥有任意多个公共字段一样。另一方面,我们可以继承Collection<T>并覆盖其虚拟以通知更改。

当集合的完整所有权转移给调用者时,

List<T>最适合作为返回值。这就是Enumerable.ToList()实际上完全合理并且不违反规则精神的原因。

现在我考虑一下,允许List<T>作为方法的返回值,但继续标记List<T>属性和参数可能会大大提高规则的信噪比......

答案 2 :(得分:3)

请记住,所有这些规则都是为框架开发人员编写的。除非您还在编写框架,否则其中许多可能不合适。

您必须对每条规则作出判断,以确定它是否适合您的情况。我喜欢使用分析,因为它确实发现了一些错误,但我总是禁用某些规则(例如,我经常有一个catch Exception作为最终的捕获 - 因为我需要记录所有类型即使无法处理,也会出现错误。)