【问题标题】:Serializing a list of anonymous delegates序列化匿名代表列表
【发布时间】:2009-10-24 17:06:45
【问题描述】:

This question 可能与我的非常相似,但我看不到我需要的答案。我有一个名为CASM 的类,它有一个List<Action>。我想序列化这个类(使用BinaryFormatter 或类似的东西)。这个类和Actions 中引用的所有类都有正确的[Serializable][NonSerializable] 属性。

尝试序列化时出现问题 - 它给出了这个错误:

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

这个&lt;&gt;c__DisplayClass2c 是一个自动生成的内部类,它包含我在我的应用程序中使用的不同类型的匿名委托。但是,从下图中我们可以看出,它不是[Serializable]

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

更改我的应用程序以使其有效的最佳方法是什么?制作我自己的&lt;&gt;c__DisplayClass2c-type 类并使其可序列化?还是有更好的办法?


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

【问题讨论】:

  • 你说这个类是自动生成的——它是怎么做的?控制它吗?它是由第 3 方组件生成的吗?
  • 它由编译器自动生成 - 它具有 [CompilerGenerated] 属性。我认为它只是一个存储许多非常相似的匿名代表的类/位置(在这种情况下,它们都是无效的,并且接受 string[] 作为参数)。
  • 然后,尝试生成自己的类。你可能也有匿名方法的问题(我没试过,所以我不知道),在这种情况下,尝试非匿名版本。如果这不起作用,您可以尝试先将方法转换为表达式(那些 应该 是可序列化的)
  • 编译表达式树遇到与您仍然需要制作自动生成类的操作完全相同的问题。

标签: c# .net serialization anonymous-methods anonymous-class


【解决方案1】:

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

另外,请注意BinaryFormatter 很脆弱,如果您打算将数据保留任意长度(但对于瞬态数据是可以接受的)

为了进一步了解,我怀疑我们需要查看一些可重现的代码。


更新:实际上,我怀疑您可以通过编写自己的显式捕获类(而不是编译器生成的类)来序列化它。但我仍然认为这个概念存在根本缺陷。而且手工编写捕获类并不好玩。


解决 cmets 中的点;重新长期存储 - 因为它是 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;}
}

如您所见 - 并不总是微不足道的(这是最简单的示例)。

【讨论】:

  • 我知道会有这样的评论出现——这似乎是一件非常奇怪的事情。但是,对于我正在尝试做的事情,代表似乎是最好的(或至少是最快的)方法。创建代表需要(相对)很长时间,所以如果我可以存储它们会很好。从 Nader Shirazie 的评论中查看 Expression Tree 后,我现在意识到我实际上是在尝试重新创建有限的 Expression Tree 系统/语法(即从委托构建代码)。为什么 BinaryFormatter 不利于数据的长期存储?
  • 啊,谢谢。那么像 protobuf-net 或 XML 这样的另一个系统不会有这个“脆弱”的问题,因为它们不存储类型/版本/程序集等?
  • 完全正确;大多数序列化程序只存储 data;这使其实现独立,并且通常更短。 BinaryFormatter 存储类型/字段信息,这是非常特定于实现的。
猜你喜欢
  • 1970-01-01
  • 2012-08-05
  • 2017-01-17
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2012-01-31
相关资源
最近更新 更多