6

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

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

C#中是否有等价的东西?例如,如果我想编写一个有副作用的 lambda 函数。

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

4

5 回答 5

7

没有什么可以阻止您在 lambda 表达式中产生副作用。

Func<int> expr = () =>
{
    Console.WriteLine("bar");
    return 1;
};
int foo = expr();
于 2010-02-25T23:44:17.827 回答
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; })(); 

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

于 2010-02-26T00:18:42.270 回答
5
int foo = (() => { printf("bar"); return 1; })();

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

int i = ((Func<int>)(() => { printf("bar"); return 1; }))();
于 2010-02-25T23:45:02.460 回答
3

我们考虑过制作比()=>{M();}定义 lambda 更简洁的语法,但还没有设法找到一种既可读性好又不易与块、集合/对象初始化程序或数组初始化程序混淆的语法。你现在被 lambda 语法困住了。

于 2010-02-26T00:21:36.800 回答
2

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

于 2010-02-25T23:44:21.743 回答