呃,先不要砸鸡蛋。我说的Lambda表达式指的是Expression<T>,不是随便哪个item => { ... }。好吧,如果你还是不明白,那么我给你一个例子:
(抱歉,原来的return item;是个笔误,现已更正为 return (item%2) == 0;

int last = 0;
var query = values.Where(
item => {
last = item;
Console.WriteLine("Last value ={0}", last);
return (item%2) == 0;
}
);
var result = query.ToArray();
只要你在C# 4.0及以下版本跑,都会编译不通过。想知道编译器提示什么,请自己动手做实验。
(补充说明,我知道3.5里面没有BlockExpression等, 这些事Fx 4.0里面才加上的,我的意思是,为啥C# 4.0没有同步增加语法支持。有人说可能是没赶上,这个有点靠谱,不过到目前为止,我还是没有看到URL。希望知道的,手握资料的能贴出来分享一下。)
好了,问题来了:为什么不支持呢?这个问题暂时我没有找到什么答案,也许你能提供标准的答案。当然,我也有一些猜测:
1、和 item => item 这样的语法可能会有点冲突,不过也很好解决:只要限制statement都必须使用花括号即可;
2、可能有些QueryProvider无法支持执行语句,比如EntityFramework里面的ObjectQuery等。 不过我也没有觉得有什么太大问题,抛异常就好了。当然,这确实可能造成一些代码编译通过,但是执行的时候抛异常,你还不知道这样的查询是哪里构造出来的。就算是这样,那也只要尽早检查就能避免有问题的语句带病走太远。
不知道F#是否支持Lambda表达式中包含语句的情况,如果支持我都要想想是否转一个语言了,因为这对某些扩展造成了很大的困扰。比如说我本来构想是这样的:
(下面这部分代码又写错了,原来是CategoryId == XXX,少了 item. )

where item.CategoryId == 1
select item;
IQueryable<int> updateAffactedLine = query.Update(
item => {
item.CategoryId = GetCategoryId(NewCategoryDropDownList);
item.LastModifyDate = DateTime.Now;
}
);
嗯,你也许会说,这怎么可能执行呢?呃,好吧,如果你不了解表达式Expression这个东西,也不了解表达式访问器ExpressionVisitor这个东西,赶紧关了这个帖子。如果你懂的话,我这么说一下你大概就明白了:
1、执行之前需要估值,比如自己写一个类似.NET 类库里面的Norminator、PartialEvaluator(参见EnumerableQuery里面的方法),这样就可以计算类似GetCategoryId(NewCategoryDropDownList)这样的表达式的实际值,变成一个ConstantExpression;
2、在经过估值之后,自己写一个Provider(或者用别的方法),将这个表达式树转换成以下Sql语句:
update Photo set CategoryId = @P0, LastModifyDate = @P1 where CategoryId = 1
现在因为C#不支持这样的语法,只能用一个很Ugly的写法:
(补充,有人说不丑啊,比之前给出的方案没有多出几个字符。问题是,丑不丑不仅仅是你鼻子长了多少个的问题,地方不对照样很丑。这里面的丑在于,代码的表面含义是“产生一个新对象,并初始化某些属性”,但实际上并非这个含义,而是修改一些已有对象的某几个属性。“一个”和“一些”,“新对象”和“修改”都是不吻合的地方,我认为这就是丑。)

where item.CategoryId == 1
select item;
IQueryable<int> updateAffactedLine = query.UpdateUgly(
() => new Page(){
CategoryId = GetCategoryId(NewCategoryDropDownList),
LastModifyDate = DateTime.Now,
}
);
上面那个写法Ugly就算了,有些时候有的问题还是解决不了,比如……算了,我觉得再说就太深了,你们会晕掉的。我们还是把本贴的焦点拉回来:
该死的C#为啥不支持Expression<T>中带语句的语法?大家热烈讨论一下吧。(为什么说不解决问题,我在后面的回复中会提到,不过深了我还不打算这里说清楚,这不是一句两句话就能说清楚的。)
(嗯,我每次想到这就烦,它阻碍了我的一些设计,不得不搞得很Ugly。然后接着就会想到,总有人对语言的优美视为XX,甚至喜欢把这些问题和Execution performance混到一块说……哦哦,又扯远了。)
(补充:事实就是如此,又有人来说Execution performance的事情了,问题是我这里压根没打算探讨这个问题。)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器