2012-05-10 15 views
25

He usado expresiones lambda en otros idiomas antes de usarlas en C#, así que tuve el hábito de usar _ para lambdas simples en la forma de Func<T, TResult>, especialmente para lambdas simples donde el cuerpo es solo una expresión que representa el valor de retorno (predicados, etc.). Sin embargo, en C#, a menudo veo que se utilizan letras individuales en lugar de _ para estos mismos tipos de expresiones lambda, como x,y,z,i,j,k. El enfoque de la letra me parece extraño ya que esas letras ya tienen otro significado típico en el uso común, para variables de bucle. _ es a menudo más fácil de leer en mi opinión. ¿El estilo de letra única es realmente el estilo establecido para lambdas en C#?Estilo C#: Lambdas, _ => o x =>?

Ejemplos:

lo que estoy acostumbrado a la escritura:

var ages = people.Select(_ => _.Age); 

lo que estoy viendo está escribiendo en su lugar:

var ages = people.Select(x => x.Age); // choice of 'x' is not consistent 
+24

nunca he visto un guión que se utiliza. –

+0

Personalmente uso 'w' para el parámetro lambda cuando es trivial entender de lo que estoy hablando. Remanente de http://research.microsoft.com/en-us/um/cambridge/projects/comega/ – Blindy

+1

Eso es solo gente que está enamorada de la concisión, personalmente uso un nombre significativo. ni x ni _ son significativos. la edad hubiera sido mi elección en tu ejemplo. –

Respuesta

46

Muchos desarrolladores de C# utilizan _ para indicar que el no se va a usar el parámetro y una letra u otro nombre corto cuando se usa el parámetro .

Otros recursos:

+1

upvote para el artículo de Charlie Flowers que explica el advenimiento del uso legítimo _. –

+1

Mis ejemplos no eran del todo correctos (debería haber usado p o person en esos ejemplos). Al principio, pensé que solo se aplicaría a casos en los que el tipo _ era genérico/desconocido, pero en todos los casos en que _ se usa, al menos debe conocerse algo sobre el tipo a menos que esté utilizando métodos en Object (en cuyo caso usarías obj o similar), para que la justificación no vuele. Esto aclara un poco las cosas. –

+0

nunca consideró usar '_' para parámetros no utilizados. ahora probablemente lo haga en todas partes. –

0

no existe un estilo 'establecido' al asignar nombres a las variables lambda. Sin embargo, un guión bajo normalmente significa algún tipo de variable de miembro de instancia, lo que significa que su estilo puede entrar en conflicto con otros estándares de nomenclatura en comparación con un nombre de variable normal.

Long Story Short - Haz lo que funcione para ti.

5

O podría utilizar un nombre con significado, p.

var ages = people.Select(person => person.Age); 
+0

Estás en lo correcto. Mis ejemplos deberían haber estado usando persona. –

22

Es un nombre variable, así que me gustaría ir con la idea de que el nombre debería transmitir la información que necesita transmitir. ¿Qué información transporta _?

Para ese mismo fin, ¿qué información transporta x?

podría escribir tu ejemplo como este:

var ages = people.Select(p => p.Age); 

La idea es que siento que la p al menos sugiere en el contexto de toda la afirmación de que es un disco people. Se podría llevarlo aún más lejos:

var ages = people.Select(person => person.Age); 

ahora que transmite al lector lo que esa variable es en realidad. Por supuesto, para una declaración tan pequeña, se puede argumentar que es excesivo. No lo creo, pero es una cuestión de preferencia. (Y no solo su preferencia, sino la preferencia de cualquiera que tenga que admitir este código.)

Para expresiones lambda complejas, más grandes, multilínea, el nombre se vuelve aún más importante.Cuanto más alejada está uno del contexto de lo que significa la variable, más debe el nombre de la variable llevar ese contexto consigo.

+6

Por supuesto, el caso de parámetros descartados (por ejemplo, para un controlador de eventos anónimos) donde está escribiendo (_, __) => {notificationEventHandler();} es donde sigo viendo (y apoyo) el uso de solo subrayado nombres. –

+1

@TetsujinnoOni: Por supuesto.En ese caso, la variable no es variable. La única información que necesita transmitir es "No soy nada, no me use". – David

+0

En segundo lugar, uso de '_ => _.method()' para una sola línea, call-call lambdas, ya que reduce el peso cognitivo de la instrucción. Especialmente cuando se usan genéricos, escribir 'x => x.method()' solo agrega la consideración de "¿Qué es esta 'x'? ¿Es una coordenada en el espacio?". Considere el siguiente caso: 'Dar (_ => _ Init().);' Se utiliza con los genéricos, el subrayado, en este caso funciona como un "símbolo de derivación". Evita la redundancia, ya que define que el tipo de argumento es obvio y puede inferirse del uso, al igual que cuando se usa 'var' para evitar la repetición de una declaración de tipo. – MaDDoX

0

Hay una razón por la que puede darle un nombre - porque a veces se puede tener múltiples entradas y la necesidad de diferenciarlos:

Func<int,int,int> product = (num1, num2) => (num1 * num2); // takes in two ints, and returns one int 
int x = product(2, 3); 
+0

Es cierto, pero no creo que de eso se trata la pregunta. –

+0

¡Entonces puedes ser un verdadero rudo! (_, __) => (_ * __); EDITAR: k, SO, naturalmente, tomó mis guiones bajos como marcadores en cursiva. Simplemente mostrando para usar doble subrayado (o más) para múltiples entradas. –

+1

@ChrisSinclair, si pones backticks alrededor de tu expresión, esos caracteres especiales se mostrarán tal como están. –

17

¿Cómo es una función lambda tan diferente de cualquier otro método. Si alguien fuera a publicar código con un método como:

public static int getAge(Person _) 
{ 
    return _.Age; 
} 

o

public static int getAge(Person x) 
{ 
    return x.Age; 
} 

¿Qué le dice?

En mi opinión, elegir el nombre de un parámetro para un lambda debe ser tan significativo como el parámetro de cualquier otro método. Podría hacer excepciones ocasionales para una función de identidad x => x porque en ese caso la variable no tiene que significar nada, realmente puede ser cualquier cosa, pero usar un guión bajo o una sola letra para todo lo que tengo en mente hace que el código sea mucho menos legible. (Muchas personas pregonan las ventajas de LINQ/Lambdas como legibilidad, que se vence si se confunden todas las variables).

+1

Votación positiva para un buen cambio de perspectiva – hspain

+0

@TetsujinnoOni si viste a alguien escribir un método 'public int getAge (Person p) {return p.Age;}' ¿qué dirías? Sé que si hubiera visto a alguien escribir diría "deberías usar una variable más significativa y no una abreviatura". No veo ninguna razón por la cual la misma lógica no se aplique por igual a un lambda. – Servy

+1

Para predicados simples, la afirmación es que un nombre de variable significativo ofusca lo que está sucediendo. En los dos casos que ha escrito, el formalismo de la definición del método aumenta la cantidad de ruido a partir del cual se debe diferenciar la señal, por lo que aumenta el costo de nombrar la variable. –

1

En C#, _ se usa para variables de clase (atributo) y _ no se usa para variables locales. Por lo tanto, es bueno usar un nombre significativo para las variables locales y la variable de clase.

Ex:

var personList = (from person in people where person.Age > 18 select person).ToList(); 
Cuestiones relacionadas