Pergunta

Eu tenho a seguinte classe:

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

   public ArrayList MyList
   {
       get { return mMyList;}
   }
}

Eu quero que os usuários sejam capazes de obter mMyList que é por isso que eu exposto a "pegar" através de uma propriedade no entanto eu não quero mudanças que eles fazem para o objeto (ou seja MyList.Add (nova Classe ());). para fazer o seu caminho de volta para minha classe.

Eu acho que eu posso retornar uma cópia do objeto, mas que pode ser lento e eu estou procurando uma maneira que irá proporcionar um erro em tempo de compilação informando o usuário que não deve esperar para ser capaz de modificar o retornou valor da propriedade.

Isso é possível?

Foi útil?

Solução

Com um ArrayList você está bastante limitada porque não há somente leitura classe de coleção não genérico na BCL. A solução rápida e suja é retornar um tipo de IEnumerable.

   public IEnumerable MyList
   {
       get { return mMyList;}
   }

Este não vai realmente impedir que alguém lançando a ArrayList, mas não vai permitir edições por padrão tanto

Você pode retornar uma lista efetivamente somente leitura chamando ArrayList.ReadOnly. No entanto, do tipo de retorno é um ArrayList para que o usuário ainda seria capaz de compilar com .Add mas que iria produzir um erro de execução.

Outras dicas

Use a ArrayList.ReadOnly () método para construir e retornar um read-only invólucro em torno da lista. ele não vai copiar a lista, mas simplesmente fazer um read-only invólucro em torno dele. A fim de obter a verificação em tempo de compilação, você provavelmente vai querer voltar a read-only invólucro como IEnumerable como @Jared sugere.

public IEnumerable MyList
{
     get { return ArrayList.ReadOnly(mMyList); }
}

Uma coleção que é somente leitura é simplesmente uma coleção com um invólucro que impede a modificação coleção. Se forem feitas alterações ao subjacente a coleção, o read-only coleção reflecte essas alterações.

Este método é um O (1) operação.

Referência

Apenas para expandir a resposta de JaredPar. Como ele disse, retornando o campo de apoio real não é completamente seguro, desde que o usuário ainda é capaz de lançar dinamicamente a volta IEnumerable a um ArrayList.

Gostaria de escrever algo como isto para ter certeza sem modificações para a lista original são feitas:

public IEnumerable MyList
{
    get
    {
         foreach (object o in mMyList)
             yield return o;
    }
}

Então, novamente, eu iria probabily também usar uma lista genérica (IEnumerable<T>) a ser tipo completamente seguro.

Use um ReadOnlyCollection.

return new ReadOnlyCollection<object>(mMyList).

Você também pode fazer o ReadOnlyCollection um campo, e ele será automaticamente refletir as mudanças na lista subjacente. Esta é a solução mais eficiente.

Se você sabe que mMyList contém apenas um tipo de objeto (por exemplo, não tem nada, mas DateTimes), você pode retornar um ReadOnlyCollection<DateTime> (ou algum outro tipo) para a segurança tipo adicional. Se você estiver usando C # 3, você pode simplesmente escrever

return new ReadOnlyCollection<DateTime>(mMyList.OfType<DateTime>().ToArray())

No entanto, isso não vai atualizar automaticamente com a lista subjacente, e também é menos eficiente (Ele irá copiar a lista inteira). A melhor opção é fazer mMyList um List<T> genérico (por exemplo, um List<DateTime>)

Você deve envolver o valor de retorno de uma leitura única coleção.

Disponível a partir .NET v2.0

    public ArrayList MyList { get; private set; }

Apenas certifique a propriedade como Sealed (ou NotInheritable em VB.NET) e somente leitura, como este:

   public sealed readonly ArrayList MyList
   {
       get { return mMyList;}
   }

Também não se esqueça de tornar o campo de apoio como somente leitura:

   private readonly ArrayList mMyList;

Mas, para inicializar o valor de mMyList, você deve inicializar só no construtor, como neste exemplo:

public SampleClass()
{
   // Initialize mMyList
   mMyList = new ArrayList();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top