Вопрос

Этот вопрос может быть, он очень похож на мой, но я не вижу в нем нужного мне ответа.У меня есть класс, который называется 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]:

альтернативный текст http://bayimg.com/image/maebbaacj.jpg

Каков был бы наилучший способ изменить мое приложение, чтобы оно действительно работало?Сделать свой собственный <>c__DisplayClass2c-ввести класс и сделать его сериализуемым?Или есть способ получше?


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

Это было полезно?

Решение

Обычно сериализовывать делегат не имеет особого смысла.Обычно вы бы предпочли пометить поля делегирования как [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;}
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top