Estou observando as novas implementações no C # 7.0 e acho interessante que elas tenham implementado funções locais, mas não consigo imaginar um cenário em que uma função local seja preferida a uma expressão lambda e qual é a diferença entre as duas.
Entendo que lambdas são anonymous
funções enquanto funções locais não, mas não consigo descobrir um cenário do mundo real, em que a função local tenha vantagens sobre as expressões lambda
Qualquer exemplo seria muito apreciado. Obrigado.
Respostas:
Isso foi explicado por Mads Torgersen no C # Design Meeting Notes, onde as funções locais foram discutidas pela primeira vez :
Para expandir um pouco mais, as vantagens são:
Atuação.
Ao criar um lambda, é necessário criar um delegado, que é uma alocação desnecessária neste caso. Funções locais são realmente apenas funções, sem necessidade de delegados.
Além disso, as funções locais são mais eficientes na captura de variáveis locais: lambdas geralmente capturam variáveis em uma classe, enquanto as funções locais podem usar uma estrutura (aprovada usando
ref
), o que evita novamente uma alocação.Isso também significa que chamar funções locais é mais barato e elas podem ser incorporadas, possivelmente aumentando ainda mais o desempenho.
As funções locais podem ser recursivas.
Os lambdas também podem ser recursivos, mas requerem código estranho, onde você primeiro atribui
null
a uma variável delegada e depois ao lambda. Funções locais podem naturalmente ser recursivas (incluindo recursivas mutuamente).As funções locais podem ser genéricas.
As lambdas não podem ser genéricas, pois precisam ser atribuídas a uma variável com um tipo concreto (esse tipo pode usar variáveis genéricas do escopo externo, mas isso não é a mesma coisa).
Funções locais podem ser implementadas como um iterador.
Lambdas não pode usar a palavra-chave
yield return
(eyield break
) para implementar aIEnumerable<T>
função -returning. Funções locais podem.As funções locais parecem melhores.
Isso não é mencionado na citação acima e pode ser apenas meu viés pessoal, mas acho que a sintaxe da função normal parece melhor do que atribuir um lambda a uma variável delegada. As funções locais também são mais sucintas.
Comparar:
fonte
Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
.object
. Portanto, as lambdas poderiam usar uma estrutura, mas precisariam ser encaixotadas, para que você ainda tivesse essa alocação adicional.Além da grande resposta de svick, há mais uma vantagem nas funções locais:
elas podem ser definidas em qualquer lugar da função, mesmo após a
return
declaração.fonte
#region Helpers
na parte inferior da função, para evitar desorganização nessa função e espicamente evitar desorganização na classe principal.Se você também quiser saber como testar a função local, verifique o JustMock, pois ele possui a funcionalidade para fazê-lo. Aqui está um exemplo simples de classe que será testado:
E aqui está a aparência do teste:
Aqui está um link para a documentação do JustMock .
Aviso Legal. Eu sou um dos desenvolvedores responsáveis pelo JustMock .
fonte
.DoNothing().OccursOnce();
e depois afirme que a chamada foi feita chamando oMock.Assert(foo);
método Se você estiver interessado em saber como outros cenários são suportados, leia o artigo de ajuda Asserting Occurrence .Uso funções in-line para evitar a pressão da coleta de lixo, especialmente quando se lida com métodos de execução mais longos. Digamos que você queira obter 2 anos ou dados de mercado para um determinado símbolo. Além disso, é possível incluir muitas funcionalidades e lógica de negócios, se necessário.
o que se faz é abrir uma conexão de soquete ao servidor e fazer um loop sobre os dados que vinculam um evento a um evento. Pode-se pensar da mesma maneira que uma classe é projetada, apenas uma não está escrevendo métodos auxiliares em todo o lugar que realmente estão trabalhando apenas para uma peça de funcionalidade. Abaixo está um exemplo de como isso pode parecer, observe que estou usando variáveis e os métodos "helper" estão abaixo do finalmente. No Finalmente, removo bem os manipuladores de eventos, se minha classe do Exchange fosse externa / injetada, não haveria nenhum manipulador de eventos pendente registrado
Você pode ver as vantagens mencionadas abaixo, aqui você pode ver uma implementação de amostra. Espero que ajude a explicar os benefícios.
fonte