真剣に、APISでリストを使用停止


List<T> コレクションにStringBuilder は文字列です.これは、コレクションを一時的に構築するためのメカニズムです.List<T> のようなものです
IReadOnlyList<Element> GetElements(IReadOnlyCollection<Element> inputElement) 
{
    var list = new List<Element>();
    foreach(var inputElem in inputElements)
    {
        if (...) 
        {
            list.Add(inputElem);
        }
    }
    return list;
}
注意List<T> 関数シグネチャには表示されません.APIが言うものは私にどんな種類のコレクションも与えます、そして、私はあなたにもう一つの有限、インデックス付きのコレクションを与えます.呼び出し元はこれを理解するために実装を読む必要はありません.
入力要素を置き換える場合、何が起こるかを見てみましょうList<T> .
IReadOnlyList<Element> GetElements(List<Element> inputElement) 
これは混乱して制限機能のシグネチャです.コレクションを返しますが、入力コレクション内の要素を追加、削除または変更することもできます.できますか.発信者は知りません.私たちのAPIがもはや明確な抽象化でないことを意味して、彼はコードを読まなければなりません.さらに、呼び出し元はArray , 安ImmutableArray またはこれらの他のコレクションは、これらが実際に我々の目的のために完全に動作するとき.
取るなList<T> 入力引数を変更することを意味しない限り、入力引数として.その場合、関数はvoid (or Task , を返します.
void AddElements(List<T> collection); // this does make sense
それでは他のケースを見てみましょう.これはどういう意味ですか.
List<Element> GetElements(IReadOnlyCollection<Element> inputElement) 
これは制限的ではありませんが、それは等しく混乱しています.この関数はコレクションを返します.なぜ?この関数は、後で変更を監視できるようにどこかへのリファレンスを格納しますか?または悪い、それが使用されている間それを変更するか?再び、これは私は私がする必要はありません実装を読むように求めている奇妙なAPIのデザインです.
帰ってくる理由があるList<T> : あなたが内部のmutableなコレクションを持っているならば、確かにそれが予想外に変更されるかもしれない外側の世界と共有するのは悪い考えです.変更可能な状態はローカルに保たれます.
厳密に言えば、IReadOnlyList<T> は、immutabilityを保証しません、しかし、それはその方向に強いメッセージを送ります.厳密に言えば、正しい戻り値の型はImmutableArray<T> or ImmutableList<T> . 私はまだ柵にいる図書館はIReadOnly インターフェースSystem.Collections.Immutable , どんな理由でも.