Pergunta

Esta questão pode ser muito semelhante à minha, mas eu não posso ver o resposta que eu preciso nele. Eu tenho uma classe, chamada CASM, que tem um List<Action>. Eu quero serializar esta classe (usando o BinaryFormatter ou algo similar). Essa classe e todas as classes referenciadas nas Actions tem [Serializable] e [NonSerializable] atributos corretos.

O problema surge quando a serialização é tentada - dá este erro:

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

Esta <>c__DisplayClass2c é uma classe interna gerada automaticamente que contém os diferentes tipos de delegado anônimo que estou usando no meu aplicativo. No entanto, como podemos ver na imagem abaixo, não é [Serializable]:

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

Qual seria a melhor maneira de mudar o meu aplicativo para isso não funciona? Fazer minha própria classe do tipo <>c__DisplayClass2c e torná-lo serializado? Ou há uma maneira melhor?


EDIT: No final, eu só fiz minha própria classe, em vez de um auto-gerada. I ajuda com a depuração, bem como, na verdade, ter um nome descritivo ao invés de apenas b__12().

Foi útil?

Solução

Ele geralmente faz muito pouco sentido para serializar um delegado. Normalmente, você iria escolher para marcar campos delegado como [NonSerialized], e recriá-lo quando necessário. Se a sua principal intenção é para armazenar os delegados, então eu recomendo pensar em uma abordagem completamente diferente, francamente.

Além disso, nota que BinaryFormatter é frágil, se você está planejando para manter os dados por qualquer período de tempo (mas aceitável para os dados transitória)

Para olhar mais longe, eu suspeito que nós precisamos de olhar para algum código reprodutível.


Update: na verdade, eu suspeito que você poderia serializá-lo por escrever suas próprias classes de captura explícita (em vez dos gerados pelo compilador). Mas eu ainda acho que o conceito é fundamentalmente falho. E escrever classes de captura com a mão não é divertido.


Para abordar os pontos em comentários; re armazenamento a longo prazo - porque é tão enervante frágil - algo tão simples como mudar a partir de:

public int Value {get;set;}

para

private int value;
public int Value {
    get {return value;}
    set {
        if(value < 0) throw new ArgumentOutOfRangeException();
        this.value = value;
    }
}

destruirá serialização; como Will montagens mudança, tipo nomes, "olhando para ele engraçado", etc.

Re os delegados; para dar um exemplo de uma captura manual; em vez de:

int i = ...
Predicate<Foo> test = delegate (Foo x) { return x.Bar == i;}

que você pode fazer:

int i = ...
MyCapture cpt = new MyCapture(i);
Predicate<Foo> test = cpt.MyMethod;

com

[Serializable]
class MyCapture {
    private int i;
    public MyCapture(int i) {this.i = i;}
    public bool MyMethod(Foo x) {return x.Bar == i;}
}

Como você pode ver -. Nem sempre trivial (este é o mais simples dos exemplos)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top