序列化一个匿名委托列表

3
这个问题可能与这个问题非常相似,但我在其中找不到我需要的答案。我有一个类叫做,它有一个。我想序列化这个类(使用或类似的东西)。这个类和中引用的所有类都有正确的和属性。
当尝试序列化时,问题就出现了-它会给出这个错误:
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()

你说这个类是自动生成的 - 它是如何实现的?你有控制权吗?它是由第三方组件生成的吗? - Nader Shirazie
它是由编译器自动生成的 - 它具有[CompilerGenerated]属性。我认为它只是一个类/位置,用于存储许多非常相似的匿名委托(在这种情况下,它们都是void并接受一个string[]作为参数)。 - Callum Rogers
那么,尝试生成自己的类。您可能还会遇到匿名方法的问题(我没有尝试过,所以不确定),如果是这样,请尝试非匿名版本。如果即使这样也不起作用,您可以先将方法转换为表达式(它们应该是可序列化的)。 - Nader Shirazie
编译表达式树遇到的问题与操作相同,仍然需要生成自动生成的类。 - Callum Rogers
1个回答

4
通常情况下,序列化委托是没有太多意义的。通常,您会选择将委托字段标记为[NonSerialized],并在需要时重新创建它。如果您的主要目的确实是存储委托,则我建议考虑完全不同的方法。
此外,请注意,如果您计划长时间保留数据,则BinaryFormatter可能不够稳健(但对于短暂数据可以接受)。
要进一步了解,我怀疑我们需要查看一些可重现的代码。
更新:实际上,我怀疑你可以通过编写自己的显式捕获类(而不是编译器生成的类)来序列化它。但我仍然认为这个概念从根本上是有缺陷的。而且手动编写捕获类也不好玩。
回应评论中的观点;关于长期存储——由于它非常脆弱——只需简单地从以下方式进行更改:
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;}
}

如您所见 - 并非总是琐碎的(这是最简单的例子)。

我知道这样的评论会出现 - 这似乎是一件非常奇怪的事情。然而,对于我正在尝试做的事情来说,委托似乎是最好的(或者至少是最快的)方法。创建委托需要(相对)很长时间,因此如果我可以存储它们就好了。在查看Nader Shirazie的评论中的表达式树之后,我现在意识到我本质上是在尝试重新创建一个有限的表达式树系统/语法(即从委托构建代码)。为什么BinaryFormatter不适合长期存储数据? - Callum Rogers
啊,谢谢。那么像 protobuf-net 或 XML 这样的另一个系统就不会有这个“脆弱”的问题,因为它们不存储类型/版本/程序集等信息? - Callum Rogers
大多数序列化程序只存储数据,这使其与实现无关且通常更短。 BinaryFormatter 存储类型/字段信息,这非常依赖于具体实现。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接