views:

166

answers:

5

back in school, we wrote a compiler where curly braces had the default behavior of executing all expressions, and returning the last value... so you could write something like:

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

Is there something equivalent in C#? For instance, if I want to write a lambda function that has a side effect.

The point less being about the lambda side effect (just an example), more if there is this functionality... for instance in lisp, you have progn

+7  A: 

There's nothing stopping you from having side-effects in a lambda expression.

Func<int> expr = () =>
{
    Console.WriteLine("bar");
    return 1;
};
int foo = expr();
Aaronaught
+2  A: 

You're talking about an anonymous function: http://msdn.microsoft.com/en-us/library/bb882516.aspx, I think.

Noon Silk
+5  A: 
int foo = (() => { printf("bar"); return 1; })();

Edit: thanks for the constructive critique, it ought to be

int i = ((Func<int>)(() => { printf("bar"); return 1; }))();
Vlad
This is the right answer -- that said, seriously consider not doing this.
Cory Petosky
You folks might want to actually check whether the code compiles before voting up. This doesn't. -1.
Aaronaught
Yes, yes, `printf` doesn't exist in C#. But the answer is not about that.
Vlad
Why does it not? It looks as if it could compile at first glance.
dtb
@Cory: definitely!
Vlad
It has nothing to do with the lack of a `printf` function. Change it to `Console.WriteLine` and you'll still get a compile error, "Method name expected".
Aaronaught
May be overly verbose, but how about `int foo = ((Func<int>)(() => { Console.WriteLine("bar"); return 1; }))();` which should compile?
jball
The answer is to illustrate how the things can be done. It doesn't contain class declaration, too. It doesn't contain `main` method, etc. etc. etc. Do you need that all?
Vlad
@Vlad: No, you don't need all that for a post on SO. You do need valid syntax. This is not valid syntax.
Aaronaught
Vlad, it won't work even with a class declaration and `main` method.
jball
@jball: Yes, that syntax does work, because of the explicit cast to a delegate. Not easy on the eyes, but it compiles.
Aaronaught
Cory Petosky
+7  A: 

In principle, the answer from Vlad is correct and you don't need to declare the lambda function as a delegate in advance.

Except, the situation is not as simple in C#, because the compiler cannot decide whether the syntactical lambda expression should be compiled as a delegate (e.g. Func<int>) or an expression tree (e.g. Expression<Func<int>>) and also, it can be any other compatible delegate type. So, you need to create the delegate:

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

You can simplify the code slightly by defining a method that simply returns the delegate and then calling the method - the C# compiler will infer the delegate type automatically:

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; })(); 

I agree that this is an ugly trick that shouldn't be used :-), but it is an interesting fact that it can be done!

Tomas Petricek
+3  A: 

We've considered making even-more-brief syntaxes than ()=>{M();} for definition of a lambda, but haven't managed to actually find a syntax that both reads nicely and is not easily confused with blocks, collection/object initializers, or array initializers. You're stuck with lambda syntax for now.

Eric Lippert