C#:是否可以在匿名方法中声明局部变量?

Nie*_*sma 13 c# lambda anonymous-methods linq-to-sql

可以在匿名c#方法中使用局部变量,即在以下代码中我只想执行一次计数.

IQueryable<Enquiry> linq = db.Enquiries;

if(...) linq = linq.Where(...);

if(...) linq = linq.Where(e => 
    (x <= (from p in db.Orders where p.EnquiryId == e.Id select p).Count() && 
        (from p in db.Orders where p.EnquiryId == e.Id select p).Count() <= y));

if(...) linq = linq.Where(...);

var result = (from e in linq select e);
Run Code Online (Sandbox Code Playgroud)

匿名函数是否有"让"?

更新:请注意,我在此语句后添加了几个Where子句,因此无法使用select关闭.

/尼尔斯

Meh*_*ari 26

是的,为什么不?!毕竟它是一个功能,只是匿名!

例:

 x => { int y = x + 1; return x + y; }
Run Code Online (Sandbox Code Playgroud)

或者:

 delegate(int x) {
     int y = x + 1;
     return x + y;
 }
Run Code Online (Sandbox Code Playgroud)

所以你的代码可以写成:

  ... = linq.Where(e => {
         var count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count();
         return x <= count && count <= y;
  });
Run Code Online (Sandbox Code Playgroud)

更新:要澄清有关注释的内容,了解匿名方法和lambda表达式之间的区别非常重要.匿名方法就像普通方法一样,没有明确的名称.编译时,编译器会生成一个带有奇怪名称的普通方法,因此它没有任何特殊限制.但是,匿名方法的一种表示形式是lambda表达式.Lambda表达式可以用几种不同的方式解释.第一个是代表.这样,它们就等于匿名方法.第二个是表达式树.这种方式通常由LINQ to SQL和其他一些LINQ提供程序使用.它们不会以任何方式直接执行您的表达式.它们将其解析为表达式树,并使用树作为输入数据来生成要在服务器上运行的等效SQL语句.它不像方法那样执行,也不被认为是匿名方法.在这种情况下,您无法定义局部变量,因为无法将lambda解析为表达式树.


Dan*_*ker 7

是的,您可以完全按照自己的意愿,在Linq中使用对象,使用Linq to SQL.

letLinq中有一个,允许您在查询中间为中间结果命名,就像您想要的那样.根据你的例子:

... = from e in linq 
      let count = (from p in db.Orders where p.EnquiryId == e.Id select p).Count()
      where (x <= count) && (count <= y)
      select e;
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我认为你的原始例子在语法上有些错误,当count它只是一个名字时更容易被发现:

where (x <= count) && /* <= */ (count <= y);
Run Code Online (Sandbox Code Playgroud)


Tor*_*och 0

我遇到了类似的问题。解决方案是创建自定义表达式树生成方法。

我在 MSDN 论坛上提出了我的问题。请参阅此处的问题和答案:重用Where表达式

这可能会让您了解如何继续,但我必须承认自定义表达式树不适合胆小的人;-)