🗣️

【 C# 】配列をプロパティとして公開しない

2022/10/11に公開

C#のコーディング規約で CA1819:プロパティは、配列を返すことはできません というのがある。

使う人は普通に使いがちであろう public string[] Names { get; private set; } こういうやつが怒られる。

なんでダメなの?というと、特にこういうふうにgetだけ公開したプロパティが外から変更されることは普通想定しないものだが、実際には上の実装だと、 foo.Names[0] = "bar" というふうに外部から更新ができてしまう。

それを避けたい場合は、↓こんなふうに実装する必要があって、、

private string[] _names;
// コピーを返す
public string[] Names => (string[])_names.Clone();

しかしこれを利用する側は Names を参照する度にコピーを生成する処理が走ることなど想定しないだろうから、プロパティにしておくのは微妙だよねということですね。

なので対処としては、単純にプロパティをやめて CloneNames() のようなメソッドにするという手もあるけど、わざわざコピーを作らせるまでもなく、配列の代わりに更新不可能なインターフェースのプロパティとして公開するのが良いです。

読み取り専用のインターフェースとしては、抽象レベルの意味合い的には IReadOnlyCollection<T> を使いたいところだが、インデクサが使えなくて微妙に使いにくいことがある。
なので、基本的に IReadOnlyList<T> にしておくのが良いんじゃないかなと思います。

Discussion