次の方法で共有


CA1846: Substring より AsSpan を優先する

プロパティ
ルール ID CA1846
Title Substring より AsSpan を優先
[カテゴリ] パフォーマンス
修正が中断ありか中断なしか なし
.NET 8 では既定で有効 提案として

原因

String.Substring オーバーロードの 1 つを呼び出した結果は、ReadOnlySpan<Char> を受け取る使用可能なオーバーロードのあるメソッドに渡されます。

規則の説明

Substring により、ヒープに新しい string オブジェクトが割り当てられ、抽出されたテキストの完全なコピーが実行されます。 多くのプログラムで、文字列操作はパフォーマンスのボトルネックになります。 ホット パスで有効期間の短い小さな文字列を多数割り当てると発生する全体的な負荷は、パフォーマンスに影響を与えるほど大きくなる可能性があります。 Substring によって作成される O(n) コピーは、部分文字列が大きくなると関連するようになります。 Span<T> および ReadOnlySpan<T> 型は、このようなパフォーマンスの問題を解決するために作成されました。

文字列を受け取る多くの API には、ReadOnlySpan<System.Char> 引数を受け取るオーバーロードもあります。 このようなオーバーロードを使用できるときは、Substring ではなく AsSpan を呼び出すことによって、パフォーマンスを向上させることができます。

違反の修正方法

この規則の違反を修正するには、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

どのようなときに警告を抑制するか

パフォーマンスが問題にならない場合は、この規則による警告を抑制しても問題ありません。

関連項目