2008-09-19 8 views
11

Con el advenimiento de nuevas características como expresiones lambda (código en línea), ¿significa que ya no tenemos que usar delegados ni métodos anónimos? En casi todas las muestras que he visto, es para reescribir utilizando la nueva sintaxis.¿Hay algún caso en el que se prefiera la sintaxis de delegado sobre la expresión lambda para métodos anónimos?

Cualquier lugar donde todavía tengamos que usar delegados y expresiones lambda no funcionará?

+0

Ver también [whats-the-difference-between-anonymous-methods-and-lambda-expressions] (http://stackoverflow.com/questions/208381/whats-the-difference-between-anonymous-methods-c -2-0-y-lambda-expressions) para las diferencias generales. – nawfal

Respuesta

8

lambda es atajo para delegado anónimo, pero siempre estará utilizando delegados. el delegado especifica la firma de los métodos. sólo se puede hacer esto:

delegate(int i) { Console.WriteLine(i.ToString()) } 

pueden ser sustituidos por

f => Console.WriteLine(f.ToString()) 
3

expresiones lambda son sólo "azúcar sintáctico", el compilador generará delegados apropiados para usted. Puedes investigar esto usando el reflector de Lutz Roeder.

+1

En realidad, las expresiones lambda son un poco más que azúcares sintácticos, ya que pueden compilarse en un árbol de expresiones y manipularse. –

+0

Reflector es ahora propiedad de redgate [http://www.red-gate.com/products/reflector/] – cori

3

Lamda de son el azúcar solo sintáctica para los delegados, que no son sólo en línea, puede hacer lo siguiente:

s.Find(a => 
{ 
    if (a.StartsWith("H")) 
     return a.Equals("HI"); 
    else 
     return !a.Equals("FOO"); 
}); 

y delegados todavía se utilizan en la definición de los eventos, o cuando usted tiene un montón de argumentos y desea de hecho, escriba fuertemente el método que se está llamando.

27

Sí, hay lugares donde el uso directo de delegados anónimos y expresiones lambda no funcionará.

Si un método toma un delegado sin tipo, entonces el compilador no sabe a qué resolver la expresión anónima de delegado/lambda y obtendrá un error de compilación.

public static void Invoke(Delegate d) 
{ 
    d.DynamicInvoke(); 
} 

static void Main(string[] args) 
{ 
    // fails 
    Invoke(() => Console.WriteLine("Test")); 

    // works 
    Invoke(new Action(() => Console.WriteLine("Test"))); 

    Console.ReadKey(); 
} 

La línea de falla del código obtendrá el error del compilador "No se puede convertir la expresión lambda para escribir 'System.Delegate' porque no es un tipo de delegado".

+0

Creo que el interlocutor pregunta si la palabra clave "delegate" está obsoleta, a favor de la sintaxis más reciente basada en lambda. Ella agrupa "métodos y delegados anónimos" juntos. – nawfal

3

El delegado tiene dos significados en C#.

La palabra clave delegate se puede usar para definir un tipo de firma de función. Esto generalmente se usa cuando se define la firma de funciones de orden superior, es decir, funciones que toman otras funciones como argumentos. Este uso de delegado sigue siendo relevante.

La palabra clave delegate también se puede usar para definir una función anónima en línea. En el caso donde la función es solo una expresión, la sintaxis lambda es una alternativa más simple.

7

La expresión lambda no es (ni estaba destinada a ser) una bala de plata que reemplazaría (ocultaría) a los delegados. Es muy bueno con pequeñas cosas locales como:

List<string> names = GetNames(); 
names.ForEach(Console.WriteLine); 
  1. que hace que el código sea más legible por lo tanto fácil de entender.
  2. Hace código más corto por lo tanto menos trabajo para nosotros;)

Por otro lado, es muy sencillo de hacer mal uso de ellos.expresiones largas y/o complejos lambda tienden a ser:

  1. difícil de entender para los nuevos desarrolladores
  2. Menos orientado a objetos
  3. más difícil de leer

Así “¿Significa que Don ¿Ya no tiene que usar delegados ni métodos anónimos? "No, use la expresión Lambda donde gane tiempo/legibilidad; de lo contrario, considere usar delegados.

+0

¡GUAU! ¡Nunca he oído hablar de este! ¿Hay forma de hacer predicado también, es decir, nombres. Donde (! String.IsNullOrEmpty)); ? Lo intenté y no funcionó para mí. ¡Uy! Si elimino el! Operand funciona, ¿por qué? Incluso traté de ponerlo entre paréntesis, pero no puede invocarlo por completo, ¿hay alguna manera? En realidad, estamos tratando de convertir string.IsNullOrEmpty en string.IsNotNullOrEmpty ... – Shimmy

2

Uno no tan grande ventaja para la sintaxis anterior delegate es que no necesita especificar los parámetros si no lo usa en el cuerpo del método. De msdn

Hay un caso en el que un método anónimo proporciona funcionalidad no se encuentra en las expresiones lambda. Los métodos anónimos le permiten omitir la lista de parámetros. Esto significa que un método anónimo puede ser convertido a delegados con una variedad de firmas. Esto no es posible con expresiones lambda.

Por ejemplo, usted puede hacer:

Action<int> a = delegate { }; //takes 1 argument, but not specified on the RHS 

Si bien esto no funciona:

Action<int> a = => { }; //omitted parameter, doesnt compile. 

Esta técnica sobre todo es muy útil cuando se escribe eventos manipuladores, como:

button.onClicked += delegate { Console.WriteLine("clicked"); }; 

Esto no es un fuerte ventaja. Es mejor adoptar la sintaxis más nueva siempre imho.

+1

En realidad, estaba buscando un caso de uso desde la madrugada de hoy para saber por qué debería especificar un argumento en una firma de método pero no usarlo en el cuerpo del método :PAG. Los manejadores de eventos parecen un ejemplo pero aún _1_. La omisión de parámetros aumenta la confusión. _2_. Mañana si me caigo en la necesidad de utilizar cualquiera de los parámetros 'object sender, EventArgs e', entonces el desarrollador debe tener en cuenta este truco de compilación específico que no es tan obvio. Para mí es un pulgar hacia abajo desde el punto de vista de una función solo para guardar dos palabras de tipeo. Estoy totalmente de acuerdo contigo en - _Esta no es una gran ventaja_ – RBT

Cuestiones relacionadas