Pergunta

Eu estou trabalhando na criação de uma classe imutável.
Eu marquei todas as propriedades como somente leitura.

Eu tenho uma lista de itens na classe.
Embora se a propriedade é somente leitura da lista pode ser modificada.

A exposição do IEnumerable da lista torna imutável.
Eu queria saber o que são as regras básicas um tem que seguir para fazer uma imutável classe?

Foi útil?

Solução

Eu acho que você está no caminho certo -

  • todas as informações injetado na classe deve ser fornecido no construtor
  • todas as propriedades devem ser getters única
  • Se uma coleção (ou Array) é passado para o construtor, ele deve ser copiado para manter o chamador de modificá-lo mais tarde
  • se você estiver indo para retornar a sua colecção, ou retornar uma cópia ou uma versão apenas de leitura (por exemplo, usando ArrayList.ReadOnly ou similar - você pode combinar isso com o ponto anterior e loja um read-only copiar a ser devolvido quando os chamadores acessá-lo), retornar um recenseador, ou usar algum outro método / propriedade que permite acesso somente leitura para a coleção
  • manter em mente que você ainda pode ter a aparência de uma classe mutável, se qualquer um dos seus membros são mutáveis ??- se este for o caso, você deve copiar afastado qualquer estado que você vai querer reter e evitar o retorno objetos mutáveis ??inteiros, a menos copiá-los antes de dar-los de volta para o chamador - outra opção é retornar apenas "seções" imutáveis ??do objeto mutável - graças a @ Brian Rasmussen por me encorajar a expandir este ponto

Outras dicas

Para ser imutável, todas as suas propriedades e campos deve ser somente leitura. E os itens em qualquer lista de si mesmos devem ser imutáveis.

Você pode fazer uma propriedade de lista somente leitura da seguinte forma:

public class MyClass
{
    public MyClass(..., IList<MyType> items)
    {
        ...
        _myReadOnlyList = new List<MyType>(items).AsReadOnly();
    }

    public IList<MyType> MyReadOnlyList
    {
        get { return _myReadOnlyList; }
    }
    private IList<MyType> _myReadOnlyList

}

Além disso, mantenha em mente que:

public readonly object[] MyObjects;

não é imutável mesmo que seja marcada com palavra-chave readonly. Você ainda pode alterar as referências de matriz / valores individuais por índice acessor.

Use a classe ReadOnlyCollection. Ele está situado no espaço de nomes System.Collections.ObjectModel.

Em qualquer coisa que retorna a sua lista (ou no construtor), defina a lista como uma coleção somente leitura.

using System.Collections.ObjectModel;

...

public MyClass(..., List<ListItemType> theList, ...)
{
    ...
    this.myListItemCollection= theList.AsReadOnly();
    ...
}

public ReadOnlyCollection<ListItemType> ListItems
{
     get { return this.myListItemCollection; }
}

Outra opção seria a utilização de um padrão do visitante em vez de expor quaisquer coleções internas em tudo.

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