C# Visual Studio代码分析规则-“;“不要公开通用列表”;
如果我的所有方法都需要公开一个集合,那么我需要使用Linq扩展名.ToList(),几乎在我所有代码中需要使用列表或用户集合的任何地方C# Visual Studio代码分析规则-“;“不要公开通用列表”;,c#,linq,extension-methods,code-analysis,fxcop,C#,Linq,Extension Methods,Code Analysis,Fxcop,如果我的所有方法都需要公开一个集合,那么我需要使用Linq扩展名.ToList(),几乎在我所有代码中需要使用列表或用户集合的任何地方 如果是这样,.ToList()会忽略规则,对吗?或者有没有一种技术,比如复制某个列表来修复冲突并仍然返回一个列表?我禁用了该规则,因为我觉得它不是一个有效的规则。如果要返回包含O(1)计数且不是对内部字段的直接引用的集合,List是最佳选择 我不太理解您的情况,但听起来您有一个方法可以返回对一些内部数据的LINQ查询。如果是这种情况,那么对数据使用.ToList
如果是这样,.ToList()会忽略规则,对吗?或者有没有一种技术,比如复制某个列表来修复冲突并仍然返回一个列表?我禁用了该规则,因为我觉得它不是一个有效的规则。如果要返回包含
O(1)
计数且不是对内部字段的直接引用的集合,List
是最佳选择
我不太理解您的情况,但听起来您有一个方法可以返回对一些内部数据的LINQ查询。如果是这种情况,那么对数据使用
.ToList()
是合适的,因为您可能不希望将来对内部字段的修改影响方法的返回值。在这种情况下,没有理由不将其作为列表公开 记住,所有这些规则都是为框架开发人员编写的。除非您也在编写框架,否则它们中的许多可能都不合适
你必须对每一条规则做出判断,看看它是否适合你的情况。我喜欢使用分析,因为它有时确实会发现一些错误,但我总是会禁用某些规则(例如,我经常会有一个捕获异常作为最终捕获,因为我需要记录所有类型的错误,即使它们无法处理)。这条规则确实很嘈杂,但是有一些非常合理的理由可以避免在库代码中列出List
。这完全取决于上下文。以下是在禁用规则或抑制给定的事件之前要考虑的一些事情:
List
对于输入参数来说通常是一个糟糕的选择,因为它迫使调用方不必要地复制数据。我见过很多代码,它们将参数声明为List
或T[]
,而IEnumerable
就足够了
List
对于属性来说也是一个糟糕的选择。考虑下面的备选方案:
public class Course {
public List<Course> Prerequisites { get; }
}
public class Course {
public Collection<Course> Prerequisites { get; }
}
公共课{
公共列表先决条件{get;}
}
公共课{
公共集合先决条件{get;}
}
其目的是调用方可以通过修改集合来更改课程的先决条件。在这种情况下,如果我们使用列表
,那么当先决条件发生变化时,课程
类无法得到通知,因为列表
不提供任何修改回调。因此,在此上下文中使用List
就像拥有任意多个公共字段一样。另一方面,我们可以将Collection
子类化,并覆盖它的虚拟对象以获得更改通知
List
将集合的全部所有权转移给调用者时,作为返回值最有效。这就是为什么Enumerable.ToList()
实际上是完全合理的,并且它没有违反规则的精神
现在我考虑一下,允许List
作为方法的返回值,但继续标记List
属性和参数可能会大大提高规则的信噪比…@Fraga,不,这不是作弊,而且我经常出于各种原因禁用某些规则。它们不是普遍的真理,通常会妨碍设计高质量的库。它们更像是“指南”。如果您希望返回列表,则最好使用IList作为返回类型。我通常仍然使用IEnumerable
作为返回类型(即使我调用.ToList()
或.ToArray()
),因为这给了实现方法更大的灵活性。当底层对象是IList
时,大多数LINQ函数都足够智能,可以优化访问。特别是,.Count()
和.ElementAt()
仍然是O(1)操作,因此返回IEnumerable
@R不会对性能造成重大影响。我认为,问题在于,如果返回列表
,则会暴露实现细节。如果您的函数以后使用了一些不同的数据结构,那么更改返回类型将是一个破坏性的更改,因此您可能最终创建一个副本或包装器来维护公共接口。您必须决定希望在公共合同中保证多少信息,而且越少越好。@Fraga,Microsoft自己的程序集不遵守此规则(请参见System.Core),因此这绝对不是一个不变的事实。如果课程
只想在其先决条件更改时得到通知,那么,BindingList
将是一个不错的选择。它有您可以订阅的事件,而不必像Collection
@benvoigt那样派生新类。还有可观察收集
。我的观点不是说Collection
一定是最好的选择,而是说List
在这种情况下是一个糟糕的选择。