2010-02-25 31 views
6

vuelta en la escuela, que escribió un compilador donde llaves tenían el comportamiento predeterminado de la ejecución de todas las expresiones, y devolver el último valor ... por lo que podría escribir algo como:C# operador de alcance

int foo = { printf("bar"); 1 }; 

¿Hay algo equivalente en C#? Por ejemplo, si quiero escribir una función lambda que tenga un efecto secundario.

El punto menos estar sobre el efecto secundario lambda (es un ejemplo), más si existe esta funcionalidad ... por ejemplo en Lisp, tiene progn

Respuesta

7

En principio, la respuesta de Vlad es correcta y que no es necesario declarar la función lambda como un delegado por adelantado.

excepción, la situación no es tan simple en C#, ya que el compilador no puede decidir si la expresión lambda sintáctico debe ser compilado como delegado (por ejemplo Func<int>) o un árbol de expresión (por ejemplo Expression<Func<int>>) y también, puede ser cualquier otro tipo de delegado compatible. Por lo tanto, es necesario crear el delegado:

int foo = new Func<int>(() => { 
    Console.WriteLine("bar"); return 1; })(); 

Se puede simplificar el código ligeramente mediante la definición de un método que simplemente devuelve el delegado y luego llamar al método - el compilador de C# inferir el tipo de delegado automáticamente:

static Func<R> Scope<R>(Func<R> f) { return f; } 

// Compiler automatically compiles lambda function 
// as delegate and infers the type arguments of 'Scope' 
int foo = Scope(() => { Console.WriteLine("bar"); return 1; })(); 

Estoy de acuerdo en que este es un truco feo que no debería usarse :-), pero es un hecho interesante que se puede hacer.

7

no hay nada que nos impida tener efectos secundarios en una expresión lambda

Func<int> expr =() => 
{ 
    Console.WriteLine("bar"); 
    return 1; 
}; 
int foo = expr(); 
5
int foo = (() => { printf("bar"); return 1; })(); 

Editar: gracias por la crítica constructiva, que debe ser

int i = ((Func<int>)(() => { printf("bar"); return 1; }))(); 
+5

Esta es la respuesta correcta, una vez dicho esto, considere seriamente no hacer esto. –

+2

Es posible que la gente quiera comprobar si el código se compila antes de votar. Esto no. -1. – Aaronaught

+0

Sí, sí, 'printf' no existe en C#. Pero la respuesta no es sobre eso. – Vlad

3

Hemos considerado hacer sintaxis aún más breves que ()=>{M();} para la definición de una lambda, pero no hemos logrado encontrar realmente una sintaxis que se lea bien y no se confunda fácilmente con bloques, inicializadores de colección/objeto, o inicializadores de matriz. Estás atrapado en la sintaxis lambda por ahora.