¿Qué significa la sintaxis '=>' en C #?

81

Acabo de encontrar esta sintaxis en algunas de las preguntas de este foro, pero Google y cualquier otro motor de búsqueda tiende a bloquear cualquier cosa menos letras y números en la búsqueda, por lo que es imposible buscar "=>".

Entonces, ¿alguien puede decirme qué es y cómo se usa?

Wolf5
fuente

Respuestas:

84

Es el operador lambda.

De C # 3 a C # 5, esto solo se usó para expresiones lambda . Estos son básicamente una forma más corta de los métodos anónimos introducidos en C # 2, pero también se pueden convertir en árboles de expresión .

Como ejemplo:

Func<Person, string> nameProjection = p => p.Name;

es equivalente a:

Func<Person, string> nameProjection = delegate (Person p) { return p.Name; };

En ambos casos, está creando un delegado con un Personparámetro, que devuelve el nombre de esa persona (como una cadena).

En C # 6 se usa la misma sintaxis para miembros con cuerpo de expresión , por ejemplo

// Expression-bodied property
public int IsValid => name != null && id != -1;

// Expression-bodied method
public int GetHashCode() => id.GetHashCode();

Ver también:

(Y, de hecho, muchas preguntas similares: pruebe las etiquetas lambda y lambda-expression ).

Jon Skeet
fuente
1
Dado que la pregunta no dice nada sobre el caso exacto sobre el que se pregunta, ¿quizás considere actualizar esta respuesta para que contenga también la nueva sintaxis del miembro con cuerpo de expresión?
Lasse V. Karlsen
1
Agradable :) Acabo de llegar aquí porque esta pregunta se usó como objetivo para el cierre duplicado, así que pensé que sería bueno tener una respuesta en lugar de ir a buscar una diferente en esos otros casos :)
Lasse V. Karlsen
14

Significa genialidad. Por ejemplo

x => x + 1

representa un método que toma x como parámetro y devuelve su sucesor.

button.Click += new EventHandler((sender, e) => methodInfo.Invoke(null, new object[] { sender, e }));

asigna un controlador de eventos a un botón invocando un método que contiene MethodInfo.

Serhat Ozgel
fuente
14

Es una forma mucho más concisa de notación de método. Los siguientes son aproximadamente equivalentes:

// explicit method
int MyFunc(int pParam) {
   return pParam;
}

// anonymous (name-less) method
// note that the method is "wrapped" up in a hidden object (Delegate) this way
// so there is a very tiny bit of overhead compared to an explicit method
// (though it's really the assignment that causes that and would also happen
// if you assigned an explicit method to a reference)
Func<int, int> MyFunc = delegate (int pParam) { return pParam; };

// lambda expression (also anonymous)
// basically identical to anonymous method,
// except with everything inferred as much as possible, intended to be minimally verbose
Func<int, int> MyFunc = x => x;

// and => is now also used for "expression-bodied" methods
// which let you omit the return keyword and braces if you can evaluate
// to something in one line
int MyFunc(int pParam) =>
   pParam;

Piense en una expresión lambda como si dijera "dado algo, devolver algo". En el ejemplo anterior, la expresión lambda x => xdice "dado x, devuelve x", aunque las expresiones lambda no necesariamente tienen que devolver algo, en cuyo caso podrías leerlas como "dado x, haz algo con x".

También tenga en cuenta que hay tres cosas llamadas "delegar" que pueden ser muy confusas al principio.

Un método anónimo usa la delegatepalabra clave, pero define un método sin nombre:

Func<int, int> = delegate (int x) { return x; };

Asignar un método (anónimo, explícito o lambda) a una referencia hace Delegateque se cree un objeto contenedor oculto que es lo que permite hacer referencia al método. (Básicamente, una especie de "puntero de función administrada").

Y luego, también puede declarar firmas de métodos nombrados usando la delegatepalabra clave también:

public delegate int TestFunc(int x, int y);

TestFunc myFunc = delegate (int x, int y) { return x + y; };

Esto declara una firma con nombre TestFuncque toma dos intsy devuelve an int, y luego declara una referencia delegada de ese tipo a la que luego se le asigna un método anónimo con una firma coincidente.

Dave Cousineau
fuente
10

aquí hay un ejemplo simple de msdn

delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

Cualquier cosa antes de => son los parámetros de entrada, y cualquier cosa después es la expresión. Puede tener varios parámetros de entrada. Las lambdas se utilizan principalmente con Linq.

Steve
fuente
8

En lugar de usar un método anónimo como este:

somevar.Find(delegate(int n)
{
   if(n < 10)
      return n;
});

simplemente escríbelo así:

somevar.Find(n => n < 10);

Tomará el tipo de datos según el valor de retorno.

milot
fuente
3

El token => se admite de dos formas: como operador lambda y como separador de un nombre de miembro y la implementación del miembro en una definición de cuerpo de expresión.

Operador lambda

En expresiones lambda, el operador lambda => separa las variables de entrada en el lado izquierdo del cuerpo lambda en el lado derecho.

El siguiente ejemplo usa la función LINQ con sintaxis de método para demostrar el uso de expresiones lambda:

string[] words = { "bot", "apple", "apricot" };
int minimalLength = words
  .Where(w => w.StartsWith("a"))
  .Min(w => w.Length);
Console.WriteLine(minimalLength);   // output: 5

Definición del cuerpo de expresión

Una definición de cuerpo de expresión tiene la siguiente sintaxis general:

member => expression;

donde expresión es una expresión válida. Tenga en cuenta que la expresión puede ser una expresión de declaración solo si el tipo de retorno del miembro es nulo o si el miembro es un constructor, un finalizador o un descriptor de acceso de conjunto de propiedades.

El siguiente ejemplo muestra una definición de cuerpo de expresión para un método Person.ToString:

public override string ToString() => $"{fname} {lname}".Trim();

Es una versión abreviada de la siguiente definición de método:

public override string ToString()
{
   return $"{fname} {lname}".Trim();
}
Sharon como
fuente
4
Si va a copiar y pegar respuestas de otros sitios web, al menos incluya un enlace a la fuente .
Knelis
1

Básicamente significa "entra", como un parámetro

MyObjectReference => MyObjectReference.DoSomething()

Por lo general, los usa para pasar funciones a métodos como parámetros o en declaraciones LINQ

MyCollection.Where(myobj => myobj.Age>10)

Por ejemplo.

qui
fuente
0

Es parte de la sintaxis de una expresión lambda. Una expresión lambda es esencialmente una forma abreviada de un delegado o de un método anónimo. Para ilustrar, suponga que tengo una serie de cadenas que coinciden con las letras del alfabeto. Podría seleccionar los miembros de esa matriz que contenían valores mayores que "E" con la siguiente expresión LINQ:

var someLetters = alphabet.Where (l => l> "E");

La parte de la expresión lambda a la izquierda de "=>" identifica el nombre de la variable para la prueba (que se establece en los miembros individuales del alfabeto) y la parte de la expresión lambda a la derecha de "=>" identifica el procesamiento. En este caso, el procesamiento produce un valor booleano que la lógica Where usa para determinar si cada miembro del alfabeto se pasa a la matriz someLetters.

JonStonecash
fuente