Pergunta

Suponha que temos:

interface Foo 
{
 bool Func(int x);
}

class Bar: Foo
{
  bool Func(int x)
  {
   return (x>0);
  }  
}

class Baz: Foo
{
  bool Func(int x)
  {
   return (x<0);
  }  
}

Agora podemos lançar ao redor Bar e Baz como um Foos e chamar seus métodos Func.

Os delegados simplificar isso um pouco:

delegate bool Foo(int x);

bool Bar(int x)
{
 return (x<0);
}

bool Baz(int x)
{
 return (x>0);
}

Agora podemos lançar ao redor Bar e Baz como delegados Foo.

O que é o benefício real de delegados, exceto para obter o código mais curto?

Foi útil?

Solução

Há uma ligeira diferença, os delegados podem acessar as variáveis ??de membro das classes em que, eles são definidos. Em C # (ao contrário de Java) toda classe interna são consideram ser estática. Portanto, se você estiver usando uma interface para gerenciar uma chamada de retorno, por exemplo, um ActionListener para um botão. A classe interna para a implantação precisa ser transmitido (via construtor) Referências às partes da classe que contém que pode ser necessário para interagir com durante o retorno de chamada. Delegados não tem essa restrição, portanto, reduz a quantidade de código necessário para implementar o retorno de chamada.

Shorter mais código, concisa é também um benefício digno.

Outras dicas

Do ponto de vista de engenharia de software que você está certo, os delegados são muito parecidos com as interfaces de função em que o protótipo de uma interface de função.

Eles também podem ser usados ??tanto no mesmo tipo de forma: em vez de passar toda uma classe em que contém o método que você precisa você pode passar em apenas um delegado. Isso economiza um monte de código e cria um código muito mais legível.

Além disso, com o advento das expressões lambda que agora também pode ser definido facilmente na mosca que é um enorme bônus. Embora seja possível para as classes construir sobre a mosca em C #, é realmente uma enorme dor na bunda.

Comparando os dois é um conceito interessante. Eu não tinha considerado anteriormente como muito semelhantes as idéias são a partir de um caso de uso e estruturação código de ponto de vista.

Um delegado faz share muito em comum com uma referência interface que tem um método único do ponto de vista do autor da chamada.

No primeiro exemplo, Baz e Bar são classes, que podem ser herdadas e instanciado. No segundo exemplo, Baz e Bar são métodos.

Você não pode aplicar as referências de interface para apenas qualquer classe que coincide com o contrato de interface. A classe deve declarar explicitamente que ele suporta a interface. Você pode aplicar uma referência delegado para qualquer método que corresponde à assinatura.

Você não pode incluir métodos estáticos em contrato de um interface. (Embora você pode trancar métodos estáticos no com métodos de extensão). Você pode se referir a métodos estáticos com uma referência delegado.

Não, delegados são para ponteiros de método. Então você pode ter certeza de que a assinatura do método associado w / o delegado está correto.

Além disso, então você não precisa conhecer a estrutura da classe. Dessa forma, você pode usar um método que você escreveu para passar para um método em outra classe, e definir a funcionalidade que você quer que aconteça.

Dê uma olhada na List <> classe com o método Find . Agora você começa a definir o que determina se algo é um jogo ou não, sem a necessidade de itens contidos na classe para implementar IListFindable ou algo similar.

Você pode passar delegados como parâmetros em funções (Ok, tecnicamente delegados se tornam objetos quando compilado, mas isso não é o ponto aqui). Você poderia passar um objeto como um parâmetro (obviamente), mas, em seguida, você está amarrando esse tipo de objeto para a função como um parâmetro. Com os delegados você pode passar qualquer função para executar no código que tem a mesma assinatura, independentemente de onde ele vem.

Pode-se pensar de delegados como uma interface para um método que define quais os argumentos e tipo de retorno de um método deve ter para caber o delegado

Sim, um delegado pode ser pensado como uma interface com um método.

Um delegado é um ponteiro método digitado. Isto dá-lhe mais flexibilidade do que as interfaces porque você pode tirar vantagem de covariância e contravariance, e você pode modificar o estado do objeto (você teria que passar a este ponteiro ao redor com functors base de interface).

Além disso, os delegados têm muito de Nice açúcar sintático que lhe permite fazer coisas como combiná-los com facilidade.

Interfaces e delegados são duas coisas totalmente diferentes, embora eu entendo a tentação de descrever delegados na interface semelhante termos de facilidade de compreensão ... no entanto, não sabendo a verdade pode levar a confusão para baixo da linha.

delegados foram inspirado (em parte) por causa da arte preto de C ++ ponteiros do método ser inadequada para determinados fins. Um exemplo clássico é a implementação de uma passagem de mensagens ou mecanismo de tratamento de eventos. Os delegados permitem definir uma assinatura de método sem qualquer conhecimento de uma classe tipos ou interfaces - eu poderia definir um 'vazio eventHandler (Evento * e)' delegado e invocá-lo em qualquer classe que implementou

.

Para alguns insights sobre este problema clássico, e por delegados são desejáveis ?? ler este e depois este .

Em, pelo menos, uma proposta para a adição de encerramentos (i.e. delegados anónimo) para Java, que são equivalentes para as interfaces com um método único membro.

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