Pergunta

Esta questão já tem uma resposta aqui:

Especificamente, alguém pode me dar exemplos concretos de quando ou quando não usar classes aninhadas?

Eu conheço sobre este recurso desde sempre, mas nunca teve uma razão para usá-lo.

Graças.

Foi útil?

Solução

Quando a classe aninhada só é usada pela classe exterior, um grande exemplo, já não é necessário, é para uma classe enumerador para uma recolha.

Outro exemplo pode ser para um enum para substituir um verdadeiro falso parâmetro utilizado por um método dentro de uma classe, para esclarecer a assinatura chamada ...

em vez de

public class Product
{
    public void AmountInInventory(int warehouseId, bool includeReturns)
    {
        int totalCount = CountOfNewItems();
        if (includeReturns)
            totalCount+= CountOfReturnedItems();
        return totalCount;
    }
}

e

  product P = new Product();
  int TotalInventory = P.AmountInInventory(123, true);  

que deixa claro o que significa 'verdadeiros', você poderia escrever:

public class Product
{
    [Flags]public enum Include{None=0, New=1, Returns=2, All=3 }
    public void AmountInInventory(int warehouseId, Include include)
    {
        int totalCount = 0;
        if ((include & Include.New) == Include.New)
            totalCount += CountOfNewItems();
        if ((include & Include.Returns) == Include.Returns)
            totalCount += CountOfReturns();
        return totalCount;
    }
}


  product P = new Product();
  int TotalInventory = P.AmountInInventory(123, Product.Include.All);  

O que faz o valor do parâmetro limpar no código do cliente.

Outras dicas

Os dois lugares onde eu usar classes aninhadas:

  • A classe aninhada é usada exclusivamente pela classe externa, e eu quero escopo totalmente privado.

  • A classe aninhada é utilizada especificamente para implementar uma interface definida em outras posições. Por exemplo, a implementação de um recenseador cai nesta categoria.

Você realmente só quer usar classes aninhadas quando tiver certeza a classe aninhada não faz sentido que seria usado em qualquer outro lugar.

Por exemplo, se for necessário para criar uma lista de vários tipos de objeto associados juntamente com funções e informações membro sobre que conjunto de objetos para um curto período de tempo (como métodos ou propriedades), você poderia usar uma classe aninhada para fazer isso . Talvez você precisa criar uma lista de todas as combinações de algum tipo de objeto e, em seguida, marcar todas as combinações que têm uma certa propriedade. Isso seria um bom caso para uma classe aninhada.

Se você não precisa de métodos na classe aninhada, provavelmente você pode usar apenas um struct , mas eu não sei se IL trata-los de forma diferente.

Às vezes eu uso isso para classes auxiliares simples que eu preciso para uma ou duas funções dentro da classe pai.

Para um exemplo prático, consulte esta pergunta feita no início desta manhã:
Faça um objeto acessível apenas um outro objeto no mesmo assembly?

Resumo:. Você pode aninhar uma classe de dados associado dentro do objeto de negócios

Já vi casos de classes aninhadas quando uma estrutura de dados de propósito específico é usado apenas dentro de uma classe, ou uma determinada exceção é lançada e pegou apenas dentro de uma classe.

I Classes ninho quando eu tiver uma classe auxiliar que não tem necessidade de ser visível para qualquer outro objeto no sistema. Isso mantém a visibilidade tão limitada quanto possível, que ajuda a evitar utilizações não previstas da classe

Na sequência do Tio Bob 'regras' em matéria de coesão deve achar que você realmente criar um grande número de classes aninhadas (e aninhadas, aninhado!). Estes poderia ser feita não-aninhada mas única se você tiver outros clientes que a referência deles agora.

Eu gostaria de melhorar minha resposta anterior!

Uma área específica onde eu usar classes aninhadas regularmente está permitindo Injection Interface e inversão de controle. Exemplo ...

public class Worker
{
  private IHelper _helper;

  public Worker()
    : this (new DefaultHelper())
  {
  }
  public Worker(IHelper helper)
  {
    this._helper = helper;
  }

  private class DefaultHelper : IHelper
  {
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top