Сериализация списка анонимных делегатов

Этот вопрос может быть очень похож на мой, но я не вижу ответа, который мне нужен. У меня есть class под названием CASM , который имеет List . Я хочу сериализовать этот class (используя BinaryFormatter или что-то подобное). Этот class и все classы, на которые ссылаются в 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 – это автогенерируемый внутренний class, который содержит различные типы анонимных делегатов, которые я использую в своем приложении. Однако, как видно из приведенного ниже изображения, это не [Serializable] :

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

Что было бы лучшим способом изменить мое приложение, чтобы это работало? Создайте свой собственный class c__DisplayClass2c и сделайте его сериализуемым? Или есть лучший способ?


EDIT: В конце концов я просто сделал свой собственный class, а не автогенерировал. Я также помогаю отлаживать, фактически имея описательное имя, а не просто b__12() .

    Обычно для сериализации делегата очень мало смысла. Обычно вы должны [NonSerialized] поля делегата как [NonSerialized] и воссоздавать его, когда это необходимо. Если ваше главное намерение состоит в том, чтобы хранить делегатов, я бы порекомендовал думать о совершенно другом подходе, честно говоря.

    Кроме того, обратите внимание, что BinaryFormatter является хрупким, если вы планируете хранить данные в течение некоторого времени (но приемлемы для временных данных)

    Чтобы посмотреть дальше, я подозреваю, что нам нужно посмотреть на какой-нибудь воспроизводимый код.


    Обновление: на самом деле, я подозреваю, что вы можете сериализовать его, написав собственные явные classы захвата (а не созданные компилятором). Но я все еще думаю, что концепция принципиально ошибочна. И писать classы захвата вручную – это не весело.


    Для рассмотрения пунктов в комментариях; долговременное хранение – потому что он настолько проклят хрупким – что-то простое, как переход от:

     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 test = delegate (Foo x) { return x.Bar == i;} 

    вы можете сделать:

     int i = ... MyCapture cpt = new MyCapture(i); Predicate 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;} } 

    Как вы можете видеть - не всегда тривиально (это самый простой из примеров).