definicao.Com esse recurso, podemos passar delegates como parametros a outros metodos e/ou guardar referencias a esses metodos para uso posterior.Delegates, assim como classes, devem ser previamente definidos e podem ser instanciados direta ou indiretamente, e apos sua instanciacao, se comportam como se fossem metodos comuns.Quando invocados, executam o metodo referenciado.Os delegates mais usados no .NET sao os do tipo: EventHandler, Action e suas variacoes, Func<TResult> e suas variacoes.Se voce utiliza .NET 3.5 ou superior, provavelmente nunca ira criar um novo tipo de delegate, basta utilizar um delegate ja existente.Declarando DelegatesPara entendermos melhor os delegates, vamos declarar alguns antes de utiliza-los. Cada linha abaixo define um delegate diferente: public delegate void VoidSemParametros(); public delegate void VoidComParametros(string valor); public delegate int IntSemParametros(); public delegate int IntComParametros(int x, int y);A primeira linha define um delegate chamado VoidSemParametros, e podemos associa-lo a um metodo em que seu retorno seja do tipo void, e que nao possua nenhum parametro. Vamos entao declarar um metodo que satisfaca essas condicoes: public void MetodoSemParametros() { Console.WriteLine("MetodoSemParametros"); }Agora que temos um metodo com assinatura e retorno compativel, podemos instanciar o delegate passando o metodo como parametro em seu construtor: /* Instancia VoidSemParametros utilizando construtor (new()) */ var delegateNew = new VoidSemParametros(MetodoSemParametros); delegateNew(); /* executa */Um outro metodo que tambem e compativel com o delegate VoidSemParametros: public void OutroMetodoSemParametros() { Console.WriteLine("OutroMetodoSemParametros"); }Dessa vez, instanciaremos o delegate passando diretamente o metodo: /* Instancia VoidSemParametros apontando direto para um metodo com assinatura compativel */ VoidSemParametros delegateExplicito = OutroMetodoSemParametros; delegateExplicito(); /* executa */Quando rodarmos este programa, ao executar o delegate, veremos que o metodo que foi passado como referencia sera executado, imprimindo alguma coisa na saida do Console.Podemos tambem instanciar um delegate via anonymous methods: /* Instancia VoidSemParametros utilizando anonymous delegate */ VoidSemParametros delegateInline = delegate() { Console.WriteLine("Anonymous delegate..."); };Tambem e possivel criar instancias de delegates atraves da combinacao de dois ou mais instancias de delegates diferentes. Quando este delegate e executado, executara os metodos referenciados na ordem em que foram "somados": /* Instancia um delegate combinando varios delegates */ var delegateCombinado = delegateInline + delegateNew;Pode-se tambem utilizar concatenacao de delegates, utilizando o operador += em um delegate previamente instanciado: /* Concatena delegates */ delegateCombinado += delegateExplicito; /* O metodo Console.WriteLine possui varias sobrecargas, uma delas possui assinatura compativel com VoidSemParametros */ delegateCombinado += Console.WriteLine; /*executa todos os delegates que foram combinados na mesma ordem*/ delegateCombinado();Agora vamos utilizar o segundo delegate que declaramos, na segunda linha, identificado como VoidComParametros. Para isso, vamos criar um metodo com assinatura compativel. O retorno deve ser void, e deve possuir um parametro do tipo string: public void Escreve(string valor) { Console.WriteLine("Valor: {0}", valor); }Seguindo a mesma linha de raciocinio, instanciaremos o delegate VoidComParametros de duas maneiras para que fique bem claro: var escreve = new VoidComParametros(Escreve); escreve("Escrito via metodo programa.Escreve"); /* O metodo Console.WriteLine possui varias sobrecargas, uma delas possui assinatura compativel com VoidComParametros */ VoidComParametros escreveDireto = Console.WriteLine; escreveDireto("Escrito via Console.WriteLine");O terceiro delegate identificado como IntSemParametros possui um retorno do tipo Int e nao possui parametros. Um metodo com assinatura compativel ficaria assim: public int FuncaoQueRetornaInt(){ return 1;