Hola y bienvenido a StackOverflow. Me tomé la libertad de editar ligeramente su pregunta para aumentar sus posibilidades de obtener respuestas útiles, espero que no le importe.
Lasse V. Karlsen
Tenga en cuenta que, asumiendo que listes un IEnumerable<T>, podrían (y deberían) haber usadosum = list.Count();
BlueRaja - Danny Pflughoeft
Supongo que esto puede usarse para evitar que "contamine" el alcance con un nuevo nombre de variable que podría usarse en otro lugar y causaría un conflicto.
Tim Schmelter
Respuestas:
84
Esa es una convención que se usa cuando no le importa el parámetro.
Es más común en Haskell y otros lenguajes funcionales. Creo que de ahí viene.
Gabe Moothart
10
En Haskell, ML, Scala y otros, _es el carácter comodín en la coincidencia de patrones. Básicamente significa "No me importa, siempre quiero que esto coincida". Este "no me importa" se transfiere cuando se trata de nombrar cosas que no te importan y, desde allí, se extiende a otros lenguajes de programación. Por ejemplo, también se usa en Ruby para significar lo mismo que en este ejemplo, aunque no _tiene absolutamente ningún significado especial en Ruby.
Es un nombre de parámetro, aunque no es útil, pero es el que se usa normalmente (según algunas convenciones) cuando necesita especificar que la expresión tiene un parámetro para que el código se compile, pero realmente no le importa al respecto, así que simplemente lo ignorará.
Básicamente, está explotando la sintaxis de lo que constituye un identificador legal en C #, y dado que un identificador puede comenzar con un guión bajo y no contener nada más, es solo un nombre de parámetro.
Sí, lo había usado cuando estaba creando un hilo usando expresión lambda. Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh
Lo que supongo es que el uso de _ pasa cada variable de la colección a la expresión lambda aunque no se use. Pero cuando usamos () puede que no suceda. Me refiero al parámetro menos lambda.
amesh
Debe probarlo usando la llamada al método ForEach. Hay una sobrecarga en el constructor de Thread que toma un delegado que no toma ningún parámetro. Intente llamar a un método, como ese ForEach, que toma un delegado que toma un parámetro en su lugar.
Lasse V. Karlsen
29
_es un nombre de variable válido. Solo lo están usando _como una variable.
Debido a que la expresión lamda se usa principalmente en un código corto y anónimo, por lo que el nombre de la variable a veces no es necesario, incluso ellos no usan la variable en el bloque de código, por lo que solo dan un _ para una convención breve
También secundo el uso de _ => _.method()lambdas de llamada de método de una línea, ya que reduce el peso cognitivo de la instrucción. Especialmente cuando se usan genéricos, la escritura x => x.method()solo agrega esa consideración de fracción de segundo de "¿Qué es esta 'x'? ¿Es una coordenada en el espacio?".
Considere el siguiente caso:
Initialize<Client> ( _=>_.Init() );
Usado con una llamada Generics, el guión bajo en este caso funciona como un "símbolo de bypass". Evita la redundancia, definiendo que el tipo de argumento es obvio y se puede inferir del uso, al igual que cuando usa 'var' para evitar que se repita una declaración de tipo. Escribir client=>client.Init()aquí solo alargaría la instrucción sin agregarle ningún significado.
Obviamente, esto no se aplica a los parámetros que se pasarán al método, que debe nombrarse de forma descriptiva. P.ej.:Do( id=>Log(id) );
El uso del parámetro de subrayado único para las llamadas a métodos es difícilmente justificable cuando se usa un bloque de código en lugar de una sola línea, ya que el identificador lambda se desconecta de su definición genérica. En general, cuando se va a reutilizar el mismo identificador, asígnele un nombre descriptivo.
La conclusión es que la verbosidad solo se justifica para la desambiguación, especialmente para las lambdas, que se crearon para simplificar la creación de delegados anónimos en primer lugar. En cualquier caso, conviene utilizar el sentido común, equilibrando la legibilidad y la concisión. Si el símbolo es sólo un "gancho" a la funcionalidad real, los identificadores de un carácter están perfectamente bien. Ese es el caso de los bucles For y las letras "i" y "j" como indexadores.
+1 para este enfoque! Pensé que era el único que usaba guiones bajos en lambdas para "reducir el peso cognitivo" y no para mostrar que este parámetro no se usa. Se lee más fácilmente con guiones bajos, especialmente si hay mucho encadenamiento y puede inferir inmediatamente el tipo, como suele ser el caso de las consultas LINQ.
list
es unIEnumerable<T>
, podrían (y deberían) haber usadosum = list.Count();
Respuestas:
Esa es una convención que se usa cuando no le importa el parámetro.
fuente
_
es el carácter comodín en la coincidencia de patrones. Básicamente significa "No me importa, siempre quiero que esto coincida". Este "no me importa" se transfiere cuando se trata de nombrar cosas que no te importan y, desde allí, se extiende a otros lenguajes de programación. Por ejemplo, también se usa en Ruby para significar lo mismo que en este ejemplo, aunque no_
tiene absolutamente ningún significado especial en Ruby.Es un nombre de parámetro, aunque no es útil, pero es el que se usa normalmente (según algunas convenciones) cuando necesita especificar que la expresión tiene un parámetro para que el código se compile, pero realmente no le importa al respecto, así que simplemente lo ignorará.
Básicamente, está explotando la sintaxis de lo que constituye un identificador legal en C #, y dado que un identificador puede comenzar con un guión bajo y no contener nada más, es solo un nombre de parámetro.
Podrías haber escrito fácilmente:
fuente
Thread t= new Thread(()=>doSomething(x,y)); t.start();
_
es un nombre de variable válido. Solo lo están usando_
como una variable.fuente
Debido a que la expresión lamda se usa principalmente en un código corto y anónimo, por lo que el nombre de la variable a veces no es necesario, incluso ellos no usan la variable en el bloque de código, por lo que solo dan un _ para una convención breve
fuente
También secundo el uso de
_ => _.method()
lambdas de llamada de método de una línea, ya que reduce el peso cognitivo de la instrucción. Especialmente cuando se usan genéricos, la escriturax => x.method()
solo agrega esa consideración de fracción de segundo de "¿Qué es esta 'x'? ¿Es una coordenada en el espacio?".Considere el siguiente caso:
Initialize<Client> ( _=>_.Init() );
Usado con una llamada Generics, el guión bajo en este caso funciona como un "símbolo de bypass". Evita la redundancia, definiendo que el tipo de argumento es obvio y se puede inferir del uso, al igual que cuando usa 'var' para evitar que se repita una declaración de tipo. Escribir
client=>client.Init()
aquí solo alargaría la instrucción sin agregarle ningún significado.Obviamente, esto no se aplica a los parámetros que se pasarán al método, que debe nombrarse de forma descriptiva. P.ej.:
Do( id=>Log(id) );
El uso del parámetro de subrayado único para las llamadas a métodos es difícilmente justificable cuando se usa un bloque de código en lugar de una sola línea, ya que el identificador lambda se desconecta de su definición genérica. En general, cuando se va a reutilizar el mismo identificador, asígnele un nombre descriptivo.
La conclusión es que la verbosidad solo se justifica para la desambiguación, especialmente para las lambdas, que se crearon para simplificar la creación de delegados anónimos en primer lugar. En cualquier caso, conviene utilizar el sentido común, equilibrando la legibilidad y la concisión. Si el símbolo es sólo un "gancho" a la funcionalidad real, los identificadores de un carácter están perfectamente bien. Ese es el caso de los bucles For y las letras "i" y "j" como indexadores.
fuente
Do(id => Log(id))
se abrevia mejor comoDo(Log)
.