CA1841:建議使用 Dictionary.Contains 方法

屬性
規則識別碼 CA1841
標題 偏好字典包含方法
類別 效能
修正程式是中斷或非中斷 不中斷
預設在 .NET 8 中啟用 建議

原因

此規則會在 或 集合上找出方法的呼叫 Contains ,而該方法可以取代為 ContainsKey 字典本身上 或 ContainsValue 方法的呼叫。 KeysIDictionary<TKey,TValue>Values

檔案描述

在 或 集合上 Keys 呼叫 Contains 通常比呼叫 ContainsKeyValuesContainsValue 字典本身更昂貴:

  • 許多字典實作會延遲具現化索引鍵和值集合,這表示存取 KeysValues 集合可能會導致額外的配置。
  • 如果索引鍵或值集合使用明確的介面實作來隱藏 上 ICollection<T> 的方法,您最終可能會呼叫 上的擴充方法 IEnumerable<T> 。 這可能會導致效能降低,尤其是在存取金鑰集合時。 大部分的字典實作都能夠提供索引鍵的快速 O(1) 內含專案檢查,而 Contains 上的 IEnumerable<T> 擴充方法通常會執行緩慢的 O(n) 內含專案檢查。

如何修正違規

若要修正違規,請分別將 或 dictionary.Keys.Containsdictionary.Values.Contains 的呼叫取代為 dictionary.ContainsKeydictionary.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

如需詳細資訊,請參閱 如何隱藏程式碼分析警告

另請參閱