2009-10-24 191 views
3

This question可能与我的很相似,但我看不到我需要的答案。我有一个班,名为CASM,有一个List<Action>。我想序列化这个类(使用BinaryFormatter或类似的东西)。此类和Action中引用的所有类都具有正确的[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是保存不同类型的匿名委托的我用我的应用程序自动生成的内部类。然而,正如我们可以从下面的图片看到,这是不是[Serializable]

alt text http://bayimg.com/image/maebbaacj.jpg

什么会改变我的应用程序,这样做的工作的最好方法?让我自己的<>c__DisplayClass2c类型的类,并使其可串行化?或者,还有更好的方法?


编辑:最后我只是做我自己的类,而不是自动生成一个。我帮助调试,实际上有一个描述性名称,而不仅仅是b__12()

+0

你说这个班是自动生成的 - 它是如何完成的?控制它吗?它是由第三方组件生成的吗? – 2009-10-24 17:24:51

+0

它由编译器自动生成 - 它具有[CompilerGenerated]属性。我认为这只是一个类/地方来存储一些非常相似的匿名代理(在这种情况下,它们都是无效的并接受一个字符串[]作为参数)。 – 2009-10-24 17:27:21

+0

然后是的,尝试创建自己的班级。你也可能有一个匿名方法的问题(我没有尝试过,所以我不知道),在这种情况下,尝试非匿名版本。如果即使这样也行不通,你可以尝试先将这些方法转换为表达式(这些_should_可序列化) – 2009-10-24 17:30:25

回答

4

序列化委托通常没什么意义。通常,您会选择将代理字段标记为[NonSerialized],并在需要时重新创建代理字段。如果你的主要意图来存储代表,那么坦率地说,我会建议你想一个完全不同的方法。

此外,注意BinaryFormatter脆,如果你打算保持数据的任何时间(但可以接受的临时数据)

为了进一步看,我怀疑我们需要看一些重复性码。


更新:其实,我怀疑你可以通过编写自己的明确捕获类(而不是编译器生成的)序列化。但我仍然认为这个概念有根本的缺陷。手写捕捉类并不好玩。


为了解决评论中的要点;再长期存储 - 因为它是so darned brittle - 这是从改变简单:

public int Value {get;set;} 

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

会破坏系列化;同样会改变程序集,输入名称,“看它有趣”等。

重回代表;举一个手动捕捉的例子;而不是:

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

你可以这样做:

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

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

正如你可以看到 - 并不总是微不足道的(这是最简单的例子)。

+0

我知道像这样的评论即将到来 - 这似乎是一件很奇怪的事情。然而,代表似乎是我尝试做的最好的(或至少是最快的)方法。创建委托需要花费相当长的时间,所以如果我能存储它们,这将是一件好事。我现在已经从Nader Shirazie的评论中看到表达式树后意识到我基本上试图重新创建有限的表达式树系统/语法(即从代表构建代码)。为什么BinaryFormatter不适合长期存储数据? – 2009-10-24 18:40:51

+0

啊,谢谢。所以像protobuf-net或XML这样的另一个系统不会有这个“脆弱”的问题,因为它们不存储类型/版本/程序集等? – 2009-10-24 21:38:13

+0

确切地说;大多数串行器仅存储* data *;这使得它实现独立,并且通常更短。 'BinaryFormatter'存储类型/字段信息,这是非常**实现特定的。 – 2009-10-25 07:26:55