Olá, bem-vindo ao StackOverflow. Tomei a liberdade de editar um pouco sua pergunta para aumentar sua chance de obter respostas úteis, espero que você não se importe.
Lasse V. Karlsen
Observe que, supondo que listseja um IEnumerable<T>, eles poderiam (e deveriam) apenas ter usadosum = list.Count();
BlueRaja - Danny Pflughoeft
Eu acho que isso pode ser usado para evitar que você "polua" o escopo com um novo nome de variável que pode ser usado em outro lugar, o que poderia causar um conflito.
Tim Schmelter
Respostas:
84
Essa é uma convenção usada quando você não se preocupa com o parâmetro.
É mais comum em Haskell e outras linguagens funcionais. Acho que é daí que vem.
Gabe Moothart
10
Em Haskell, ML, Scala e outros, _é o caractere curinga na correspondência de padrões. Basicamente, significa "Eu não me importo, sempre quero que combine". Esse "eu não me importo" é transportado quando se trata de nomear coisas com as quais você não se importa e, a partir daí, se espalha para outras linguagens de programação. É, por exemplo, também usado em Ruby para significar a mesma coisa que neste exemplo, embora não _tenha absolutamente nenhum significado especial em Ruby.
É um nome de parâmetro, embora não seja útil, mas é o normalmente usado (por algumas convenções) quando você precisa especificar que a expressão tem um parâmetro para obter o código para compilar, mas você realmente não se importa sobre isso, então você simplesmente vai ignorá-lo.
Basicamente, ele explora a sintaxe do que constitui um identificador legal em C # e, como um identificador pode começar com um sublinhado e não conter mais nada, é apenas um nome de parâmetro.
Sim, usei-o quando estava criando um thread usando a expressão lambda. Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh
O que presumo é que o uso de _ está passando cada variável da coleção para a expressão lambda, embora não seja usada. Mas quando usamos () isso pode não acontecer. Quero dizer parâmetro menos lambda.
amesh
Você precisa tentar usando a chamada de método ForEach. Há uma sobrecarga no construtor Thread que leva um delegado que não leva nenhum parâmetro. Tente chamar um método, como o ForEach, que usa um delegado que usa um parâmetro no lugar.
Lasse V. Karlsen
29
_é um nome de variável válido. Eles estão usando apenas _como uma variável.
Como a expressão lamda é usada principalmente em um código anônimo curto, de modo que o nome da variável às vezes não é necessário, mesmo que não usem a variável no bloco de código, eles apenas fornecem um _ para uma convenção curta
Também apoio o uso de _ => _.method()para lambdas de chamada de método de uma linha, uma vez que reduz o peso cognitivo da instrução. Especialmente ao usar genéricos, escrevendox => x.method() apenas adiciona aquela consideração de fração de segundo de "O que é este 'x'? É uma coordenada no espaço?".
Considere o seguinte caso:
Initialize<Client> ( _=>_.Init() );
Usado com uma chamada Genérica, o sublinhado neste caso funciona como um "símbolo de desvio". Isso evita redundância, definindo que o tipo do argumento é óbvio e pode ser inferido pelo uso - assim como quando você usa 'var' para evitar a repetição de uma declaração de tipo. Escrevendoclient=>client.Init() aqui apenas tornaria a instrução mais longa, sem adicionar nenhum significado a ela.
Obviamente, isso não se aplica aos parâmetros a serem passados ao método, que devem ser nomeados de forma descritiva. Por exemplo.:Do( id=>Log(id) );
O uso do parâmetro de sublinhado único para chamadas de método dificilmente se justifica ao usar um bloco de código em vez de uma linha, uma vez que o identificador lambda é desconectado de sua definição genérica. Em geral, quando o mesmo identificador deve ser reutilizado, dê a ele um nome descritivo.
O resultado final é que a verbosidade só é justificável para desambiguação, especialmente para lambdas, que foram criados para simplificar a criação de delegados anônimos em primeiro lugar. Em qualquer caso, o bom senso deve ser usado, equilibrando legibilidade e concisão. Se o símbolo for apenas um "gancho" para a funcionalidade real, os identificadores de um caractere são perfeitamente adequados. Esse é o caso com loops For e as letras "i" e "j" como indexadores.
1 para esta abordagem! Achei que fosse o único a usar sublinhados em lambdas para "diminuir o peso cognitivo" e não para mostrar que esse parâmetro não é utilizado. É mais fácil ler com sublinhados, especialmente se houver muito encadeamento e você puder inferir imediatamente o tipo, como costuma ser o caso com consultas LINQ!
list
seja umIEnumerable<T>
, eles poderiam (e deveriam) apenas ter usadosum = list.Count();
Respostas:
Essa é uma convenção usada quando você não se preocupa com o parâmetro.
fonte
_
é o caractere curinga na correspondência de padrões. Basicamente, significa "Eu não me importo, sempre quero que combine". Esse "eu não me importo" é transportado quando se trata de nomear coisas com as quais você não se importa e, a partir daí, se espalha para outras linguagens de programação. É, por exemplo, também usado em Ruby para significar a mesma coisa que neste exemplo, embora não_
tenha absolutamente nenhum significado especial em Ruby.É um nome de parâmetro, embora não seja útil, mas é o normalmente usado (por algumas convenções) quando você precisa especificar que a expressão tem um parâmetro para obter o código para compilar, mas você realmente não se importa sobre isso, então você simplesmente vai ignorá-lo.
Basicamente, ele explora a sintaxe do que constitui um identificador legal em C # e, como um identificador pode começar com um sublinhado e não conter mais nada, é apenas um nome de parâmetro.
Você poderia facilmente ter escrito:
fonte
Thread t= new Thread(()=>doSomething(x,y)); t.start();
_
é um nome de variável válido. Eles estão usando apenas_
como uma variável.fonte
Como a expressão lamda é usada principalmente em um código anônimo curto, de modo que o nome da variável às vezes não é necessário, mesmo que não usem a variável no bloco de código, eles apenas fornecem um _ para uma convenção curta
fonte
Também apoio o uso de
_ => _.method()
para lambdas de chamada de método de uma linha, uma vez que reduz o peso cognitivo da instrução. Especialmente ao usar genéricos, escrevendox => x.method()
apenas adiciona aquela consideração de fração de segundo de "O que é este 'x'? É uma coordenada no espaço?".Considere o seguinte caso:
Initialize<Client> ( _=>_.Init() );
Usado com uma chamada Genérica, o sublinhado neste caso funciona como um "símbolo de desvio". Isso evita redundância, definindo que o tipo do argumento é óbvio e pode ser inferido pelo uso - assim como quando você usa 'var' para evitar a repetição de uma declaração de tipo. Escrevendo
client=>client.Init()
aqui apenas tornaria a instrução mais longa, sem adicionar nenhum significado a ela.Obviamente, isso não se aplica aos parâmetros a serem passados ao método, que devem ser nomeados de forma descritiva. Por exemplo.:
Do( id=>Log(id) );
O uso do parâmetro de sublinhado único para chamadas de método dificilmente se justifica ao usar um bloco de código em vez de uma linha, uma vez que o identificador lambda é desconectado de sua definição genérica. Em geral, quando o mesmo identificador deve ser reutilizado, dê a ele um nome descritivo.
O resultado final é que a verbosidade só é justificável para desambiguação, especialmente para lambdas, que foram criados para simplificar a criação de delegados anônimos em primeiro lugar. Em qualquer caso, o bom senso deve ser usado, equilibrando legibilidade e concisão. Se o símbolo for apenas um "gancho" para a funcionalidade real, os identificadores de um caractere são perfeitamente adequados. Esse é o caso com loops For e as letras "i" e "j" como indexadores.
fonte
Do(id => Log(id))
é melhor abreviado comoDo(Log)
.