3

データ ツリーをデータ バックエンドとして持つアプリケーションがあります。MVVM パターンを実装するために、データ ツリーをカプセル化するクラスのロジック レイヤーがあります。したがって、ロジックもツリーに配置されます。入力が有効な状態にある場合、データは、最後の有効な状態のダブル バッファーとして機能する 2 番目のスレッドにコピーする必要があります。したがって、1 つの方法はクローン作成です。

もう 1 つのアプローチは、完全なデータ バックエンドを不変に実装することです。これは、何か新しいものが入力された場合、データ ツリー全体を再構築することを意味します。私の質問は、これを行う実用的な方法はありますか? データ ツリーをロジック レイヤーに効率的に再割り当てする必要があるところで行き詰まっています。

**更新 - いくつかのコード

私たちが行っていることは、実験を実行するために使用するハードウェア デバイスを抽象化することです。そのため、「シャーシ、シーケンス、カード、チャネル、ステップ」などのクラスを定義しました。それらは次のようなツリー構造を構築します。

                            Chassis
                          /      \
                   Sequence1      Sequence2
                   /    |    \
              Card1   Card2  Card3
             /     \
     Channel1      Channel2
    /        \
Step1        Step2

コードでは次のようになります。

public class Chassis{

readonly var List<Sequence> Sequences = new List<Sequence>();

}

public class Sequence{

readonly var List<Card> Cards = new List<Card>();

}

等々。もちろん、各クラスにはさらにいくつかのプロパティがありますが、それらは簡単に処理できます。私の問題は、 List が変更可能なオブジェクトであることです。List.Add() を呼び出すと、変更されました。わかりました ReadOnlyList がありますが、不変性が正しい方法で実装されているかどうかはわかりません。参照ではなく値によるコピーと同じように、set メソッドをブロックして書き込みをブロックするだけではありません。次の問題は、シーケンスとステップの量が変動する可能性があることです。このため、リスト要素のアトミック交換が必要です。現時点では、この方法が役立つかどうか、妥当な時間内に実装できるかどうかをまだ考えているため、これ以上のコードはありません。

4

2 に答える 2

4

目標の達成に役立つ.NET 用の新しい不変コレクションがあることに注意してください。

Dave Turvey の発言には十分注意してください (できれば反対票を投じたり、コメントしたりします)。

不変リストの実装を検討している場合は、リストをプライベート メンバーとして格納し、パブリック メンバーを公開してみてください。IEnumerable<>

これは正しくありません。プライベート メンバーは、そのコンテナー クラスによって変更される可能性があります。public メンバーは、例外をスローせずにList<T>IList<T>、またはにキャストできます。ICollection<T>したがって、パブリックの不変性に依存するものはすべてIEnumerable<T>壊れる可能性があります。

于 2013-01-15T17:23:28.480 に答える
0

あなたが求めていることを 100% 理解しているかどうかはわかりません。特定の状態のオブジェクトのツリーがあり、元のオブジェクトの状態を変更せずに、そのコピーに対して何らかの処理を実行したいと考えているようです。「ディープコピー」によるクローン作成を検討する必要があります。この質問から始めましょう。

不変リストの実装を検討している場合は、リストをプライベート メンバーとして格納し、パブリック メンバーを公開してみてください。IEnumerable<>

public class Chassis
{

   List<Sequence> _sequences = new List<Sequence>();
   public IEnumerable<Sequence> Sequences { get { return _sequences; } }

}

18/04/13 Brandon Bonds のコメントに応じて更新

Brandon Bonds answer にリンクされているライブラリは確かに興味深いものであり、IEnumerable<>. 多くの場合、それはおそらくより良い解決策です。ただし、このライブラリを使用する場合に注意すべき点がいくつかあります。

  1. 2013 年 4 月 18 日現在、これはベータ版のライブラリです。明らかにまだ開発中であり、本番環境で使用する準備ができていない可能性があります。たとえば、リンクされた記事のリスト作成のコード サンプルは、現在の nuget パッケージでは機能しません。

  2. これは .net 4.5 ライブラリです。そのため、古いフレームワークを対象とするプログラムには適していません。

  3. コレクション自体のコレクションのみに含まれるオブジェクトの不変性は保証されません。不変リスト内のオブジェクトを変更することは可能ですが、コレクションをコピーするためのディープ コピーを検討する必要があります。

これについては、記事の最後にある FAQ で説明されています

Q: これらの不変コレクションには、不変データのみを保存できますか?

A: これらのコレクションには、すべての種類のデータを格納できます。唯一の不変の側面はコレクション自体であり、コレクションに含まれるアイテムではありません。

さらに、次のコード サンプルはこの点を示しています (バージョン 1.0.8-beta を使用)。

class Data
{
    public int Value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var test = ImmutableList.Create<Data>();           
        test = test.Add(new Data  { Value = 1 });
        Console.WriteLine(test[0].Value);
        test[0].Value = 2;
        Console.WriteLine(test[0].Value);
        Console.ReadKey();
    }
}

このコードは、Data オブジェクトと出力の変更を許可します。

1
2

このトピックについてさらに読むための記事をいくつか紹介します

于 2012-11-07T12:38:35.203 に答える