Cause
Code compares two strings in a case-insensitive manner by first calling System.String.ToLower, System.String.ToLowerInvariant, System.String.ToUpper, or System.String.ToUpperInvariant on one or both strings.
Rule description
When code calls System.String.ToLower, System.String.ToLowerInvariant, System.String.ToUpper, or System.String.ToUpperInvariant, an allocation is performed. If the only reason for calling these methods is to perform a case-insensitive string comparison or search, the allocation is unnecessary. Instead, you can call a string comparison method that takes a System.StringComparison and specify one of the *IgnoreCase values.
How to fix violations
Remove the call to System.String.ToLower, System.String.ToLowerInvariant, System.String.ToUpper, or System.String.ToUpperInvariant, and either call one of the System.StringComparer methods, or one of the following methods that takes a System.StringComparison argument:
- System.String.Compare(System.String,System.String,System.StringComparison)
- System.String.Contains(System.String,System.StringComparison)
- System.String.EndsWith(System.String,System.StringComparison)
- System.String.Equals(System.String,System.StringComparison)
- System.String.IndexOf
- System.String.LastIndexOf
- System.String.Replace(System.String,System.String,System.StringComparison)
- System.String.StartsWith(System.String,System.StringComparison)
- System.Uri.Compare(System.Uri,System.Uri,System.UriComponents,System.UriFormat,System.StringComparison)
- Microsoft.Extensions.Primitives.StringSegment.Compare(Microsoft.Extensions.Primitives.StringSegment,Microsoft.Extensions.Primitives.StringSegment,System.StringComparison)
- Microsoft.Extensions.Primitives.StringSegment.EndsWith(System.String,System.StringComparison)
- Microsoft.Extensions.Primitives.StringSegment.Equals
- Microsoft.Extensions.Primitives.StringSegment.StartsWith(System.String,System.StringComparison)
Example
The following example shows a violation of the rule:
string s1 = "aBc";
string s2 = "aBC";
int _ = s1.ToUpper().CompareTo(s2.ToUpper());Dim s1 As String = "aBc"
Dim s2 As String = "aBC"
Dim i As Integer = s1.ToUpper().CompareTo(s2.ToUpper())The following example shows code that fixes the violation:
string s1 = "aBc";
string s2 = "aBC";
int _ = StringComparer.CurrentCultureIgnoreCase.Compare(s1, s2);Dim s1 As String = "aBc"
Dim s2 As String = "aBC"
Dim i As Integer = StringComparer.CurrentCultureIgnoreCase.Compare(s1, s2)When to suppress warnings
It's safe to suppress warnings from this rule if performance isn't a concern.
If you're using Entity Framework Core (EF Core), you should suppress this rule for scenarios where you're querying a database by comparing a string. EF Core throws an exception if you use a method such as System.String.Equals(System.String,System.StringComparison) that takes a System.StringComparison argument, as it won't translate such queries to SQL. For more information, see Translation of built-in .NET string operations.
Suppress a warning
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
#pragma warning disable CA1862
// The code that's violating the rule is on this line.
#pragma warning restore CA1862To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA1862.severity = noneFor more information, see How to suppress code analysis warnings.