1

IReadOnlyList<T>読み取り専用リストを作成することを調べました。しかし、100% 読み取り専用ではないと思います。リストからアイテムを追加/削除することはできませんが、メンバーを変更することはできます。

この例を考えてみましょう。

class Program
{
    static void Main(string[] args)
    {
        List<Test> list = new List<Test>();
        list.Add(new Test() { MyProperty = 10 });
        list.Add(new Test() { MyProperty = 20 });

        IReadOnlyList<Test> myImmutableObj = list.AsReadOnly();

        // I can modify the property which is part of read only list
        myImmutableObj[0].MyProperty = 30;
    }
}

public class Test
{
    public int MyProperty { get; set; } 
}

本当に読み取り専用にするにはMyProperty、読み取り専用にする必要があります。これはカスタム クラスです。クラスを変更することができます。私のリストがゲッターとセッターの両方のプロパティを持つ組み込みの.netクラスの場合はどうなりますか? その場合、値の読み取りのみを許可するその.netクラスのラッパーを作成する必要があると思います。

既存のクラスを不変にする方法はありますか?

4

2 に答える 2

6

immutableread-onlyという用語を混同しています。

読み取り専用オブジェクトは、それを変更する方法を公開しないオブジェクトです。 ReadOnlyCollection<T>( によって返されるAsReadOnly()) が良い例です)。ただし、IEnumerable<T>読み取り専用でもあります。
重要な違いは、読み取り専用オブジェクトは変更できることです。

を記述するlist.Add(new Test())と、読み取り専用コレクション ( をラップするだけlist) が変更されます。

読み取り専用コレクションは、コレクションの所有者だけがコレクションを変更できる安全な API を設計するのに役立ちます。
ただし、スレッドセーフには何の役にも立ちません。


不変オブジェクトとは、何が起こってもまったく変更できないオブジェクトです(リフレクションはカウントされません) string不変クラスの優れた例です。string何が起こっても、既存のインスタンスの値は決して変更できません。(リフレクション、安全でないコード、および特定のマーシャリング トリックを除く)

.Net には組み込みの不変コレクションはありませんが、CLR チームは NuGet で不変コレクション型のライブラリをリリースしました

真に不変なオブジェクトは、本質的にスレッドセーフです。それらを変更する方法がないため、他のスレッドが一貫性​​のないインスタンスを観察する可能性はありません。


あなたは深い不変性について尋ねています。
プロパティを介して再帰的にアクセスできるすべてのオブジェクト (オブジェクト グラフ全体) 自体が完全に不変である場合、そのオブジェクトは完全に不変です。

参照する必要があるすべてのクラスの不変バージョンを作成しない限り、完全に不変なオブジェクトを作成することはできません。これらの不変バージョンは、変更可能な元のクラスから状態をコピーする必要があります。元のインスタンスを単純にラップすることはできません。そうしないと、内部インスタンスを介して変更可能になります。

代わりに、変更可能なクラスの周りに読み取り専用のラッパーを作成することで、完全に読み取り専用のオブジェクトを作成できます。


詳細については、私のブログを参照してください。

于 2013-06-09T17:36:26.887 に答える
2

真の不変クラスとは、プロパティとフィールドがすべて読み取り専用のクラスです。この定義は、このクラスのフィールドとプロパティに含まれるすべてのクラスが読み取り専用でなければならないという点で再帰的です。リストの内容は、変更できると言ったように不変ではないため、読み取り専用リストは真に不変ではありません。IReadOnlyList<T>を真に不変にするためには、リスト内の個々の項目も読み取り専用にする必要があります。

于 2013-06-09T17:37:36.263 に答える