代码之家  ›  专栏  ›  技术社区  ›  Callum Rogers

序列化匿名委托列表

  •  3
  • Callum Rogers  · 技术社区  · 16 年前

    This question 可能和我的很相似,但我看不到我需要的答案。我有个班,叫 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 是一个自动生成的内部类,它包含我在应用程序中使用的不同类型的匿名委托。但是,正如我们从下图中看到的,它不是 [可序列化] :

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

    更改我的应用程序以使其正常工作的最佳方法是什么?做我自己 <>显示等级2c -键入类并使其可序列化?还是有更好的方法?


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

    1 回复  |  直到 15 年前
        1
  •  4
  •   Marc Gravell    16 年前

    序列化委托通常没有什么意义。通常,您会选择将委托字段标记为 [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;}
    }
    

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