匿名デリゲートのリストをシリアル化する
-
06-07-2019 - |
質問
この質問は私の質問と非常に似ているかもしれませんが、答えが必要です。 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;}
}
ご覧のとおり-常に些細なことではありません(これは最も単純な例です)。