Eu vim para usar o LINQ na minha programação diária todos os dias. De fato, raramente, se é que alguma vez, uso um loop explícito. Descobri, no entanto, que não uso mais o SQL como sintaxe. Eu apenas uso as funções de extensão. Então, ao invés de dizer:
from x in y select datatransform where filter
Eu uso:
x.Where(c => filter).Select(c => datatransform)
Qual estilo de LINQ você prefere e com que outras pessoas de sua equipe se sentem confortáveis?
c#
coding-style
linq
Erin
fonte
fonte
Respostas:
Acho lamentável que a postura da Microsoft de acordo com a documentação do MSDN seja de que a sintaxe da consulta seja preferível, porque eu nunca a uso, mas uso a sintaxe do método LINQ o tempo todo. Adoro poder disparar consultas de uma linha para o conteúdo do meu coração. Comparar:
Para:
Mais rápido, menos linhas, e aos meus olhos parece mais limpo. A sintaxe da consulta também não suporta todos os operadores LINQ padrão. Um exemplo de consulta que fiz recentemente se parecia com isso:
Que eu saiba, para replicar essa consulta usando a sintaxe da consulta (na medida do possível), ficaria assim:
Não parece mais legível para mim e você precisaria saber como usar a sintaxe do método de qualquer maneira. Pessoalmente, estou realmente apaixonado pelo estilo declarativo que o LINQ torna possível e o uso em qualquer situação em que seja possível - talvez às vezes em meu prejuízo. Caso em questão, com a sintaxe do método, posso fazer algo assim:
Eu imagino que o código acima seria difícil de entender para alguém que entra no projeto sem uma boa documentação e, se não tiver um histórico sólido no LINQ, poderá não entender de qualquer maneira. Ainda assim, a sintaxe do método expõe uma capacidade bastante poderosa para projetar rapidamente (em termos de linhas de código) uma consulta para obter informações agregadas sobre várias coleções que, de outra forma, exigiriam muitos ciclos tediosos de foreach. Em um caso como esse, a sintaxe do método é ultra compacta para o que você obtém dela. Tentar fazer isso com a sintaxe da consulta pode ficar difícil de usar rapidamente.
fonte
Acho a sintaxe funcional mais agradável aos olhos. A única exceção é se eu precisar juntar mais de dois conjuntos. O Join () fica louco muito rapidamente.
fonte
É tarde demais para adicionar outra resposta?
Eu escrevi uma tonelada de código LINQ para objetos e afirmo que, pelo menos nesse domínio, é bom entender as duas sintaxes para usar o que for mais simples - o que nem sempre é uma sintaxe de pontos.
É claro que há momentos em que a sintaxe de pontos é o caminho a seguir - outros forneceram vários desses casos; no entanto, acho que as compreensões foram modificadas - dado um mau rap, se você quiser. Então, fornecerei uma amostra em que acredito que as compreensões são úteis.
Aqui está uma solução para um quebra-cabeça de substituição de dígitos: (solução escrita usando o LINQPad, mas pode ser autônoma em um aplicativo de console)
... que produz:
Não é tão ruim, a lógica flui linearmente e podemos ver que ela apresenta uma única solução correta. Esse quebra-cabeça é fácil de resolver manualmente: raciocinar que 3>>
N
0 eO
> 4 * N implica 8> =O
> = 4. Isso significa que há um máximo de 10 casos para testar manualmente (2 porN
5 por 5)O
) Já me desviei o suficiente - esse quebra-cabeça é oferecido para fins de ilustração do LINQ.Transformações de compilador
O compilador faz muito para traduzir isso em sintaxe de ponto equivalente. Além da segunda e
from
SelectMany
habitual cláusulas subseqüentes serem transformadas em chamadas , temoslet
cláusulas que se tornamSelect
chamadas com projeções, as quais usam identificadores transparentes . Como estou prestes a mostrar, ter que nomear esses identificadores na sintaxe de pontos afasta a legibilidade dessa abordagem.Eu tenho um truque para expor o que o compilador faz ao traduzir esse código para sintaxe de ponto. Se você descomentar as duas linhas comentadas acima e executá-las novamente, obterá o seguinte resultado:
Colocando cada operador LINQ em uma nova linha, traduzindo os identificadores "indizíveis" para aqueles que podemos "falar", alterando os tipos anônimos para sua forma familiar e alterando o
AndAlso
jargão da árvore de expressão para&&
expor as transformações que o compilador faz para chegar a um equivalente na sintaxe de pontos:Que, se você executar, poderá verificar se o resultado é novamente:
... mas você escreveria um código como este?
Aposto que a resposta é NONBHN (não apenas não, mas não!) - porque é muito complexo. Claro que você pode criar nomes de identificadores mais significativos que "temp0" .. "temp3", mas o ponto é que eles não adicionam nada ao código - eles não fazem o código ter um desempenho melhor, eles não faça com que o código seja lido melhor, eles apenas o tornam feio e, se você o estivesse fazendo manualmente, sem dúvida você o estragaria uma ou três vezes antes de acertar. Além disso, jogar "o jogo do nome" já é difícil o suficiente para identificadores significativos, por isso congratulo-me com a pausa do jogo do nome que o compilador me fornece na compreensão de consultas.
Esse exemplo de quebra-cabeça pode não ser do mundo real o suficiente para você levar a sério; no entanto, existem outros cenários em que as compreensões da consulta brilham:
Join
eGroupJoin
: o escopo das variáveis de intervalo nasjoin
cláusulas de compreensão de consulta transformam erros que de outra forma poderiam ser compilados na sintaxe de pontos em erros de tempo de compilação na sintaxe de compreensão.from
cláusulas,join
ejoin..into
cláusulas elet
cláusulas.Conheço mais de uma loja de engenharia em minha cidade natal que proibiu a sintaxe de compreensão. Eu acho que é uma pena, já que a sintaxe da compreensão é apenas uma ferramenta e uma ferramenta útil. Eu acho que é como dizer, "Há coisas que você pode fazer com uma chave de fenda e que não pode fazer com um cinzel. Como você pode usar uma chave de fenda como um cinzel, os formões são proibidos a partir de agora por decreto do rei".
fonte
Meu conselho é usar a sintaxe de compreensão de consulta quando toda a expressão puder ser feita na sintaxe de compreensão. Ou seja, eu preferiria:
para
Mas eu preferiria
para
Eu gostaria que tivéssemos inventado alguma sintaxe que tornasse melhor misturar os dois. Algo como:
Mas, infelizmente, não o fizemos.
Mas, basicamente, é uma questão de preferência. Faça o que parecer melhor para você e seus colegas de trabalho.
fonte
var londonCustomers = from c in ...; int count = londonCustomers.Count();
Como o SQL, é uma boa maneira de começar. Porém, como é limitado (suporta apenas as construções suportadas pelo seu idioma atual), os desenvolvedores acabam adotando o estilo dos métodos de extensão.
Gostaria de observar que existem alguns casos que podem ser facilmente implementados no estilo semelhante ao SQL.
Além disso, você pode combinar os dois lados em uma consulta.
fonte
Eu costumo usar a sintaxe que não é de consulta, a menos que precise definir uma variável no meio do caminho, embora a consulta como
mas escrevo a sintaxe sem consulta, como
fonte
Eu sempre uso as funções de extensão por causa do pedido. Pegue o seu exemplo simples - no SQL, você escreveu select primeiro - embora, na verdade, o local onde foi executado primeiro. Quando você escreve usando os métodos de extensão, sinto-me muito mais no controle. Recebo o Intellisense sobre o que está em oferta, escrevo as coisas na ordem em que elas acontecem.
fonte
Também gosto da função de extensão.
Talvez porque seja menos um salto de sintaxe em minha mente.
Parece mais legível aos olhos também, especialmente se você estiver usando estruturas de terceiros que possuem linq api.
fonte
Aqui está a heurística que eu sigo:
Eu acho que lambdas com junções parecem bagunçadas e difíceis de ler.
fonte