質問

この質問は私の質問と非常に似ているかもしれませんが、答えが必要です。 CASMというクラスがあり、List<Action>があります。このクラスをシリアル化したい(BinaryFormatterまたは類似のものを使用)。このクラスとAction sで参照されるすべてのクラスには、正しい[Serializable]および[NonSerializable]属性があります。

シリアル化が試行されるときに問題が発生します-このエラーが発生します:

Type 'CASM.CASM+<>c__DisplayClass2c' in Assembly 'CASM, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' is not marked as serializable.

この<>c__DisplayClass2cは、アプリケーションで使用しているさまざまな種類の匿名デリゲートを保持する自動生成された内部クラスです。ただし、下の画像からわかるように、b__12()

ではありません

代替テキストhttp://bayimg.com/image/maebbaacj.jpg

これが機能するようにアプリケーションを変更する最良の方法は何ですか?独自の<=>-typeクラスを作成し、シリアル化可能にしますか?または、より良い方法がありますか?


編集:最終的には、自動生成されたクラスではなく、独自のクラスを作成しました。デバッグにも役立ちます。実際には<=>ではなく、わかりやすい名前を付けます。

役に立ちましたか?

解決

通常、デリゲートをシリアル化することはほとんど意味がありません。通常、デリゲートフィールドを[NonSerialized]としてマークし、必要に応じて再作成することを選択します。主な目的がデリゲートを保存することである場合、率直に言って、まったく異なるアプローチを考えることをお勧めします。

さらに、データを任意の期間保持することを計画している場合、BinaryFormatterは脆弱であることに注意してください(ただし、一時的なデータには許容されます)

さらに調べるには、再現可能なコードを調べる必要があると思います。


更新:実際には、(コンパイラによって生成されたものではなく)独自の明示的なキャプチャクラスを記述することで、シリアル化できると思われます。しかし、私はまだ概念が根本的に欠陥があると思います。また、キャプチャクラスを手書きで書くのは楽しくありません。


コメントのポイントに対処するには、長期保存について-ひどく脆い-次から変更するだけの簡単なもの:

public int Value {get;set;}

to

private int value;
public int Value {
    get {return value;}
    set {
        if(value < 0) throw new ArgumentOutOfRangeException();
        this.value = value;
    }
}

シリアル化を破壊します。アセンブリの変更、名前の入力、<!> quot;それを見て面白い<!> quot;など

再委任;手動キャプチャの例を示します。代わりに:

int i = ...
Predicate<Foo> test = delegate (Foo x) { return x.Bar == i;}

あなたがするかもしれない:

int i = ...
MyCapture cpt = new MyCapture(i);
Predicate<Foo> test = cpt.MyMethod;

with

[Serializable]
class MyCapture {
    private int i;
    public MyCapture(int i) {this.i = i;}
    public bool MyMethod(Foo x) {return x.Bar == i;}
}

ご覧のとおり-常に些細なことではありません(これは最も単純な例です)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top