CA1819で怒られたら
CA1819 : Microsoft.Performance : コレクションを返すために、またはメソッドに設定するために'SomeClass.SomeByteArrayGetOnly' を変更してください。
こういう文章を見ると、そもそも日本語で表示すること事態が問題にも思える。
CA1819が言いたいことは、 ArrayのPropertyはGetだけにしていても実際は中身を弄れちゃうから危ないよ ということ。
setがなくても中身の変更はできちゃうんですよね。
Arrayは参照型
そも、Arrayは参照型なので、やり取りされるのはメモリ上の所在。
またArrayは先頭番地を持つ事になるので、Arrayを箱でイメージすると
一つの型のサイズ分の幅と、初期化した時にセットした個数分の高さを持つ箱
の先頭番地をやり取りすることになる。
なのでPropertyをGetだけにする、という事は
- 新しい箱の場所を指定する
- 別の形の箱に置き換える
などができなくなるだけで、箱の中身云々の操作については制限できていない。
じゃあどうすりゃええのん
- MSDN的にはArrayのクローンを返す様にする
- ReadOnlyCollectionにする
クローンを返す、の実効的なメリットがよく分からない。 ので大人しくReadOnlyCollectionにしといたら良いと思う。
なので、これを
public byte[] SomeArray{get;}
こうする
private readonly byte[] someArray; public ReadOnlyCollection<byte> => Array.AsReadOnly(someArray);
でも、そもそもプロパティにgetだけ書くってことは弄られたくないってことなんだから
それが出来ちゃうアクセサーの仕様のがおかしくない?とも思う。
箱のサイズと場所は弄れないようにしたいけど中身はご自由にどうぞ、にしたいパターンってある?
参考
#003 Rhino.mocsでスタブの引数のコールバックに任意の値を注入する
と、いうかStubが実行されたときに任意のArgを色々する方法
そもそも何でRhino.mocsなん、という所については少し前に書かれたテストをメンテしないといけなかったから。
target.Stub( s=>s.DoSomething( Arg1, Arg<Action<string>>.Is.NotNull )) .WhenCalled( action =>{ var test =action.Argument[1] as Action<T>; test?.Invoke("注入したいもの"); } ) .Return("targetの戻り値"); )
というかRhino.mocsの情報は新しいのあんまりないと思ったらここ2014年辺りから更新されてないとか何とか…