Alguma compreensão pessoal de delegação, funções anônimas, expressões Lambda em C #

0x01 define um delegado, que é equivalente a definir um tipo de variável especial que pode armazenar um método

Abaixo, examinamos o código específico, através do código para entender melhor

delegate void IntMethodInvoker(int x);

Essa linha de código é declarar um delegado, que delegateé uma palavra-chave, que significa declarar um delegado, voidé o tipo de retorno do método a ser armazenado, IntMethodInvokeré o nome do tipo de delegado declarado, combinado com a primeira frase, o nome do tipo de variável do livro de classes personalizado int xÉ o tipo de retorno do método a ser armazenado


Quais métodos esse representante pode armazenar?

Desde que o tipo de retorno seja o mesmo , os métodos com a mesma lista de parâmetros podem ser armazenados

Neste exemplo, o tipo de retorno é nulo e existe um método do parâmetro int

void test(int t)
{
    Console.WriteLine("Just a test" + t )
}

Esse método de teste pode ser armazenado na IntMethodInvokerinstância delegada

O delegado é um tipo especial de objeto. Depois de definir o delegado, você pode criar uma instância e armazenar o método

IntMethodInvoker DelegateTest = test;

Essa linha de código armazenará o endereço do método de teste na IntMethodInvokerinstância delegada DelegateTest, e o DelegateTestmétodo de teste poderá ser executado apenas chamando-o no futuro .

DelegateTest(32);

Essa linha de código test(32)tem o mesmo efeito


Os representantes podem adicionar várias referências de método e os representantes que adicionam várias referências de método são chamados de representantes de difusão seletiva.

Adicione várias referências de método usando + =, para excluir as referências de método adicionadas use- =

0x02 Use delegados para passar métodos como parâmetros

Como dissemos anteriormente que delegação é semelhante à definição de um tipo de variável especial que pode armazenar um método, também podemos usar esse tipo especial como parâmetro formal de um método, adicionar uma referência de método à instância delegada e, em seguida, usar a instância delegada como outra delegada aceite O parâmetro real do método do tipo parâmetro, para obter o efeito de passar o método para outro método

class Program
{

    static void Main(string[] args)
    {
        Test test = new Test();
        Test.TestDelegate testDelegate = new Test.TestDelegate(test.Fun);

        test.KK(testDelegate);
    }
}
class Test
{
    public delegate void TestDelegate();

    public void Fun()
    {
        Console.WriteLine("这是一个简单的方法!");
    }
    public void KK(TestDelegate testDelegate)
    {
        Console.WriteLine("这是一个接收委托的方法");
        testDelegate();
    }
}

Este é um exemplo de passagem de um método como parâmetro para outro método

Neste exemplo, primeiro declare uma instância de Teste e, em seguida, declare uma TestDelegateinstância de delegadotestDelegate

testDelegatetest.Fun()A referência contida no delegado não é chamada no momento test.Fun(), mas a referência é salva

Próxima execução test.KK(testDelegate), quando o testDelegatedelegado for passado para o método KK como um parâmetro formal

Quando o método KK é chamado testDelegate();, delegue o método Fun

Portanto, o resultado final da execução é

Este é um método para receber um delegado,
é um método simples!

0x03 Func<T>eAction<T>

Os delegados são muito comuns; portanto, a .Net possui dois tipos de delegados incorporados, para que não tenhamos que declarar o delegado

Action<T>Delegado genérico significa se referir a um método do tipo de retorno nulo. Existem diferentes variantes desse delegado e métodos que requerem 0 a 16 parâmetros podem ser aceitos

Func<T>Delegados genéricos são Action<T>semelhantes, mas se referem a um método que possui um tipo de valor de retorno. Func<T>O método também pode receber 0 ~ 16 parâmetros, o último padrão é o tipo de retorno, ou seja, Fun<T>até dezessete parâmetros

Func<string,string,int>

Este Func indica que ele pode receber uma lista de parâmetros como duas strings e retornar um método int.

0x03Lambda e métodos anônimos

Método anônimo:

Func<string, string> anonDel = delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

O papel dos métodos anônimos:

Delegados são referências a métodos armazenados, ou seja, para usar um delegado, você deve primeiro ter um método, mas, de fato, muitas vezes a referência de método armazenada no delegado será usada apenas no delegado ou no evento (evento baseado no delegado) É muito problemático definir um método separadamente. No momento, você pode usar o método anônimo. O método acima é anônimo. Vamos olhar para a direita

delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

Este é um método anônimo, usando delegatepalavras-chave, se o delegatesubstituirmos por um nome comum

KK (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

Esse é um método comum (o ponto-e-vírgula no final é o fim da instrução de atribuição de delegação Fun); portanto, o método anônimo é um método comum para remover o nome do método e substituí-lo por um delegado para simplificar o código.

Func<string, string> anonDel = 

delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

É fácil de entender?

Expressão lambda:

No meu entendimento, as expressões Lambda são na verdade para simplificar métodos anônimos

Ainda usamos o código acima

//匿名方法
delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
}


//Lambda表达式
(string pram) =>
{
    param += mid;
    param += " and this was added to the string.";
    return param;
}

Essas duas versões são equivalentes. => É o operador Lambda. Agora vamos ver quais são os dois lados, a lista de parâmetros à esquerda e o corpo do método à direita.

Este Lambda é realmente um pouco mais complicado, geralmente encontramos o Lambda que será mais simplificado

  • Se houver apenas um parâmetro, apenas o nome do parâmetro será suficiente, ou seja, neste Lambda, (carrinho de string) poderá ser reescrito como carrinho de bebê
  • Se o corpo do método tiver apenas uma linha de instruções, não serão necessárias chaves e declarações de retorno no bloco de métodos

Por exemplo

Func<double,double> square = (double x) =>
{
    return x*x;
};

Essa expressão Lambda pode ser abreviada como

Func<double,double> square = x => x*x

Problema de fechamento de expressão lambda

Aqui está uma sentença, na expressão Lambda usa uma variável externa (não a variável na expressão Lambda), o valor da variável externa é determinado no momento da chamada, não quando a expressão Lambda é definida

int someVal = 5;
Func<int, int> ZZ = x => x + someVal;
someVal = 7;
Console.WriteLine(ZZ(3));

A última saída é 7, porque someVal já é igual a 7 quando o delegado ZZ chama a expressão Lambda

Acho que você gosta

Origin www.cnblogs.com/wujuncheng/p/12700157.html
Recomendado
Clasificación