CA1841:首选字典包含方法
属性 | 值 |
---|---|
规则 ID | CA1841 |
标题 | 首选 Dictionary.Contains 方法 |
类别 | “性能” |
修复是中断修复还是非中断修复 | 非中断 |
在 .NET 8 中默认启用 | 作为建议 |
原因
此规则可找到在 IDictionary<TKey,TValue> 的 Keys
或 Values
集合上对 Contains
方法的调用,这些调用可替换为在字典本身对 ContainsKey
或 ContainsValue
方法的调用。
规则说明
对 Keys
或 Values
集合调用 Contains
通常比对字典本身调用 ContainsKey
或 ContainsValue
开销更高:
- 许多字典实现会延迟对键值集合的实例化,这意味着访问
Keys
或Values
集合可能导致额外的分配。 - 如果键/值集合使用显式接口实现来隐藏 ICollection<T> 上的方法,可能最终会对 IEnumerable<T> 上调用扩展方法。 这可能会降低性能,尤其是在访问键集合时。 大多数字典实现都能为键提供快速的 O(1) 包含检查,而 IEnumerable<T> 上的
Contains
扩展方法通常执行较慢的 O(n) 包含检查。
如何解决冲突
若要解决冲突,请将对 dictionary.Keys.Contains
或 dictionary.Values.Contains
的调用分别替换为对 dictionary.ContainsKey
或 dictionary.ContainsValue
的调用。
下面的代码片段显示了冲突示例及其解决方法。
using System.Collections.Generic;
// Importing this namespace brings extension methods for IEnumerable<T> into scope.
using System.Linq;
class Example
{
void Method()
{
var dictionary = new Dictionary<string, int>();
// Violation
dictionary.Keys.Contains("hello world");
// Fixed
dictionary.ContainsKey("hello world");
// Violation
dictionary.Values.Contains(17);
// Fixed
dictionary.ContainsValue(17);
}
}
Imports System.Collection.Generic
' Importing this namespace brings extension methods for IEnumerable(Of T) into scope.
' Note that in Visual Basic, this namespace is often imported automatically throughout the project.
Imports System.Linq
Class Example
Private Sub Method()
Dim dictionary = New Dictionary(Of String, Of Integer)
' Violation
dictionary.Keys.Contains("hello world")
' Fixed
dictionary.ContainsKey("hello world")
' Violation
dictionary.Values.Contains(17)
' Fixed
dictionary.ContainsValue(17)
End Sub
End Class
何时禁止显示警告
如果有问题的代码不会对性能造成重大影响,可安全地禁止显示此规则发出的警告。
抑制警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#pragma warning disable CA1841
// The code that's violating the rule is on this line.
#pragma warning restore CA1841
若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none
。
[*.{cs,vb}]
dotnet_diagnostic.CA1841.severity = none
有关详细信息,请参阅如何禁止显示代码分析警告。