CA1819:プロパティは、配列を返すことはできません

ルール ID CA1819
カテゴリ パフォーマンス
修正が中断ありか中断なしか あり

原因

プロパティが配列を返します。

既定では、この規則の対象は外部から参照可能なプロパティと型のみですが、これは構成可能です。

規則の説明

プロパティが読み取り専用であっても、プロパティで返される配列は書き込みから保護されません。 配列の改ざんを防ぐには、プロパティで配列のコピーを返す必要があります。 一般に、このようなプロパティを呼び出すときのパフォーマンス低下は理解されません。 具体的には、プロパティがインデックス付きプロパティとして使用されることがあります。

違反の修正方法

この規則違反を修正するには、プロパティをメソッドに設定するか、コレクションを返すようにプロパティを変更します。

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

Attribute クラスから派生した属性のプロパティに対して表示される警告を抑制できます。 属性には、配列を返すプロパティを含めることができますが、コレクションを返すプロパティを含めることはできません。

プロパティがデータ転送オブジェクト (DTO) クラスの一部である場合は、警告を抑制できます。

それ以外の場合、この規則による警告は抑制しないでください。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable CA1819
// The code that's violating the rule is on this line.
#pragma warning restore CA1819

ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none に設定します。

[*.{cs,vb}]
dotnet_diagnostic.CA1819.severity = none

規則のこのカテゴリ全体を無効にするには、構成ファイルでカテゴリの重要度を none に設定します。

[*.{cs,vb}]
dotnet_analyzer_diagnostic.category-Performance.severity = none

詳細については、「コード分析の警告を抑制する方法」を参照してください。

分析するコードを構成する

次のオプションを使用して、コードベースのどの部分に対してこの規則を実行するか構成します。

このオプションを構成できる対象は、この規則だけ、すべての規則、このカテゴリ (パフォーマンス) のすべての規則のいずれかです。 詳細については、「コード品質規則の構成オプション」を参照してください。

特定の API サーフェイスを含める

ユーザー補助に基づいて、この規則を実行するコードベースの部分を構成できます。 たとえば、非パブリック API サーフェイスでのみ規則を実行するように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

dotnet_code_quality.CAXXXX.api_surface = private, internal

違反の例

次の例では、この規則に違反するプロパティを示します。

public class Book
{
    private string[] _Pages;

    public Book(string[] pages)
    {
        _Pages = pages;
    }

    public string[] Pages
    {
        get { return _Pages; }
    }
}
Public Class Book
    Public Sub New(ByVal pages As String())
        Me.Pages = pages
    End Sub

    Public ReadOnly Property Pages() As String()
End Class

この規則違反を修正するには、プロパティをメソッドに設定するか、配列ではなくコレクションを返すようにプロパティを変更します。

プロパティをメソッドに変更します。

次に、プロパティをメソッドに変更することによって、違反を修正する例を示します。

Public Class Book

    Private _Pages As String()

    Public Sub New(ByVal pages As String())
        _Pages = pages
    End Sub

    Public Function GetPages() As String()
        ' Need to return a clone of the array so that consumers            
        ' of this library cannot change its contents            
        Return DirectCast(_Pages.Clone(), String())
    End Function

End Class
public class Book
{
    private string[] _Pages;

    public Book(string[] pages)
    {
        _Pages = pages;
    }

    public string[] GetPages()
    {
        // Need to return a clone of the array so that consumers            
        // of this library cannot change its contents            
        return (string[])_Pages.Clone();
    }
}

コレクションを返すようにプロパティを変更する

次に、System.Collections.ObjectModel.ReadOnlyCollection<T> を返すようにプロパティを変更することによって、違反を修正する例を示します。

public class Book
{
    private ReadOnlyCollection<string> _Pages;
    public Book(string[] pages)
    {
        _Pages = new ReadOnlyCollection<string>(pages);
    }

    public ReadOnlyCollection<string> Pages
    {
        get { return _Pages; }
    }
}
Public Class Book
    Public Sub New(ByVal pages As String())
        Me.Pages = New ReadOnlyCollection(Of String)(pages)
    End Sub

    Public ReadOnly Property Pages() As ReadOnlyCollection(Of String)

End Class

ユーザーにプロパティの変更を許可する

クラスのユーザーがプロパティを変更できるようにすることができます。 次に、この規則に違反する読み取り/書き込みプロパティの例を示します。

public class Book
{
    private string[] _Pages;

    public Book(string[] pages)
    {
        _Pages = pages;
    }

    public string[] Pages
    {
        get { return _Pages; }
        set { _Pages = value; }
    }
}
Public Class Book
    Public Sub New(ByVal pages As String())
        Me.Pages = pages
    End Sub

    Public Property Pages() As String()

End Class

次に、System.Collections.ObjectModel.Collection<T> を返すようにプロパティを変更することによって、違反を修正する例を示します。

Public Class Book
    Public Sub New(ByVal pages As String())
        Me.Pages = New Collection(Of String)(pages)
    End Sub

    Public ReadOnly Property Pages() As Collection(Of String)
End Class
public class Book
{
    private Collection<string> _Pages;

    public Book(string[] pages)
    {
        _Pages = new Collection<string>(pages);
    }

    public Collection<string> Pages
    {
        get { return _Pages; }
    }
}