CA1846:首选 AsSpan 次选 Substring

属性
规则 ID CA1846
标题 首选 AsSpan 次选 Substring
类别 “性能”
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用 作为建议

原因

对其中一个 String.Substring 重载的调用结果被传递给具有接受 ReadOnlySpan<Char> 的可用重载的方法。

规则说明

Substring 在堆上分配一个新的 string 对象并执行提取文本的完整副本。 字符串操作是多个程序的性能瓶颈。 在热路径上分配很多生存期较短的小型字符串可以产生足够的集合压力来影响性能。 当子字符串变大时,Substring 创建的 O(n) 副本将变得举足轻重。 为了解决这些性能问题,创建了 Span<T>ReadOnlySpan<T> 类型。

许多接受字符串的 API 也具有接受 ReadOnlySpan<System.Char> 参数的重载。 当此类重载可用时,可以通过调用 AsSpan 而不是 Substring 来提升性能。

如何解决冲突

若要修复与此规则的冲突,请将对 string.Substring 的调用替换为对其中一个 MemoryExtensions.AsSpan 扩展方法的调用。

using System;

public void MyMethod(string iniFileLine)
{
    // Violation
    int.TryParse(iniFileLine.Substring(7), out int x);
    int.TryParse(iniFileLine.Substring(2, 5), out int y);

    // Fix
    int.TryParse(iniFileLine.AsSpan(7), out int x);
    int.TryParse(iniFileLine.AsSpan(2, 5), out int y);
}
Imports System

Public Sub MyMethod(iniFileLine As String)
    Dim x As Integer
    Dim y As Integer

    ' Violation
    Integer.TryParse(iniFileLine.Substring(7), x)
    Integer.TryParse(iniFileLine.Substring(2, 5), y)

    ' Fix
    Integer.TryParse(iniFileLine.AsSpan(7), x)
    Integer.TryParse(iniFileLine.AsSpan(2, 5), y)
End Sub

何时禁止显示警告

如果不考虑性能,可禁止显示此规则的警告。

另请参阅