C#范围运算符

时间:2010-02-25 23:41:31

标签: c# scope curly-braces

回到学校,我们编写了一个编译器,其中花括号具有执行所有表达式的默认行为,并返回最后一个值......所以你可以编写如下内容:

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

C#中有相同的东西吗?例如,如果我想写一个有副作用的lambda函数。

关于lambda副作用(仅仅是一个例子)更少,如果有这个功能则更多......例如在lisp中,你有progn

5 个答案:

答案 0 :(得分:7)

没有什么能阻止你在lambda表达中产生副作用。

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

答案 1 :(得分:7)

原则上,Vlad的答案是正确的,您不需要事先将lambda函数声明为委托。

除了C#中的情况并不那么简单,因为编译器无法决定语法lambda表达式是应该编译为委托(例如Func<int>)还是表达式树(例如Expression<Func<int>>)而且,它可以是任何其他兼容的委托类型。因此,您需要创建委托:

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

您可以通过定义一个简单地返回委托然后调用该方法的方法来稍微简化代码 - C#编译器将自动推断委托类型:

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

我同意这是一个不应该使用的丑陋技巧:-),但这是一个有趣的事实,它可以做到!

答案 2 :(得分:5)

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

编辑:感谢建设性的批评,它应该是

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

答案 3 :(得分:3)

我们考虑过制作比()=>{M();}更简单的语法来定义lambda,但是还没有设法找到一个既能很好地读取又不容易与块混淆的语法,集合/对象初始值设定项或数组初始值设定项。你现在仍然坚持使用lambda语法。

答案 4 :(得分:2)

你说的是一个匿名函数:http://msdn.microsoft.com/en-us/library/bb882516.aspx,我想。