Pergunta

Eu tenho uma classe que estou usando como uma classe de configurações que é serializada em um arquivo XML que os administradores podem editar para alterar as configurações no aplicativo. (As configurações são um pouco mais complexas que o app.config permite.)

Estou usando a classe XMLSerializer para deseralizar o arquivo XML e quero que ele seja capaz de definir a classe de propriedade, mas não quero que outros desenvolvedores usem a classe/montagem para poder definir/alterar a propriedade através do código. Posso fazer isso acontecer com a classe XMLSerializer?

Para adicionar mais alguns detalhes: esta classe em particular é uma coleção e, de acordo com o FXCOP, a classe XMLSerializer possui suporte especial para a dessertação de coleções somente leitura, mas não consegui encontrar mais informações. Os detalhes exatos sobre a regra que isso viola é:

Propriedades que as coleções de retorno devem ser somente leitura para que os usuários não possam substituir completamente a loja de apoio. Os usuários ainda podem modificar o conteúdo da coleção chamando métodos relevantes na coleção. Observe que a classe XMLSerializer possui suporte especial para a Deserializing Somente Coleções de leitura. Consulte a visão geral do XMLSerializer para obter mais informações.

É exatamente isso que eu quero, mas como isso faz isso?

Editar: Ok, acho que estou ficando um pouco louco aqui. No meu caso, tudo o que eu precisava fazer era inicializar o objeto de coleta no construtor e, em seguida, remover o criador de propriedades. Em seguida, o objeto XMLSerializable realmente sabe usar as propriedades Add/AddRange e Indexer no objeto de coleta. O seguinte realmente funciona!

public class MySettings
{
    private Collection<MySubSettings> _subSettings;
    public MySettings()
    {
       _subSettings = new Collection<MySubSettings>();
    }

    public Collection<MySubSettings> SubSettings
    {
         get { return _subSettings; }
    }
}
Foi útil?

Solução

Você precisa usar um tipo de lista mutável, como Arraylist (ou Ilist IIRC).

Outras dicas

@Rob Cooper acertou, basta implementar o Iserializable Interface e você poderá ter controle personalizado sobre como sua classe serializa e Deserialzes e definir os campos manualmente. É um pouco mais de trabalho nas pernas, mas atingirá o objetivo desejado. Boa sorte.

Eu não acho que você possa usar a serialização automática, pois a propriedade é apenas leitura.

Meu curso de ação seria implementar o Iserializable Interface e faça isso manualmente. Você poderá definir os valores internos daqui.

No entanto, se seus subobjetos (que são expostos apenas como leitura) podem cuidar de serializar-se, tudo deve funcionar.

Eu acho que a regra que o FXCOP está gemendo é que você tem algo como:

public List<MyObject> Collection
{
   get { return _collection; }
   set { _collection = value; }
}

Não é? Caso contrário, você pode colar algum código para que eu possa ver o que exatamente você está fazendo? Existem várias maneiras de fazer todas as opções acima :)

A resposta de @Leppie foi realmente a mais próxima. Este é o texto relevante real na documentação do XMLSerializer e veja minha edição à pergunta acima para obter mais detalhes:

O XMLSerializer fornece um tratamento especial para classes que implementam ienumerable ou icollection. Uma classe que implementa o IEnumerable deve implementar um método de adição público que pegue um único parâmetro. O parâmetro do método ADD deve ser do mesmo tipo que é retornado da propriedade atual no valor retornado do getenumerator ou uma das bases desse tipo. Uma classe que implementa o ICOLLECTION (como a coleta), além do IEnumerable, deve ter uma propriedade indexada por itens públicos (indexador em C#) que leva um número inteiro e deve ter uma propriedade de contagem pública do tipo inteiro. O parâmetro do método Add deve ser o mesmo tipo que é retornado da propriedade do item ou de uma das bases desse tipo. Para classes que implementam o ICOLLECTION, os valores a serem serializados são recuperados da propriedade de itens indexados, não chamando o Getenumerator.

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