LINQ查询表达式翻译?

我正在为一些自定义对象添加LINQ接口,但C#编译器在类型推断上失败。但是,我可以使用原始扩展方法和类型推断成功编写等效查询,因此我不确定编译器如何将查询表达式转换为扩展方法调用。 是否有工具或编译器标志,以便我可以查看编译器从我的查询表达式生成的内容,所以我想出来了? 此代码位于开源项目中,因此如果有用,我可以提供源代码链接。扩展方法的类型签名的轻微变化避免了这种类型的推理错误,但这些变体没有我所追求的语义。     
已邀请:
您的查询理解代码是:
from f1 in e1
from f2 in e2
from f3 in e3
select f3
您的方法调用代码是:
e1
.SelectMany(f1 => e2)
.SelectMany(f2 => e3), (f2, f3) => f3))
查询转换如下进行。首先,我们处理前两个条款:
from f1 in e1
from f2 in e2
from f3 in e3
select f3;
这被翻译成
from x in ( e1 ) . SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } )
from f3 in e3
select f3;
其中“x”是透明标识符。由于e1,e2或e3都不消耗任何范围变量,因此这是一个透明标识符的事实是无关紧要的;不需要进一步重写来处理透明标识符语义。 然后将结果转化为
( ( e1 ) . SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } ) ) 
.SelectMany( x => e3 , ( x , f3 ) => f3 )
我们可以删除其中一些括号:
e1 
.SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } ) ) 
.SelectMany( x => e3 , ( x , f3 ) => f3 )
显然,这与您手动完成的语法转换有很大的不同,回想一下
e1
.SelectMany(f1 => e2)
.SelectMany(f2 => e3), (f2, f3) => f3))
如果将e1,e2,e3替换为上面的实际语法转换,结果表达式是否会传递类型推断? 如果没有,那么问题是“为什么不呢?”您的代码有问题,或类型推导者有问题。如果类型推断器出现问题,请告诉我。 如果确实如此,则问题是“句法转换通过有什么问题”?如果句法转换过程出现问题,请再次告诉我。 谢谢!     
您可以使用Reflector并在关闭优化的情况下查看代码。     
Eric的概述让我了解了如何处理这些查询。问题是我试图以查询翻译不喜欢的方式约束正在操作的类型。
from x in Foo.Bar()
...
Foo.Bar()应该返回Future,x也应该是Future类型,但这不适用于查询转换。我通过添加另一层间接来解决这个问题,基本上包括期货,例如Async< T>类型,只能用期货来实例化,即。
public sealed class Async<T> { internal T value; }
public static class Async
{
   public static Async<Future<T>> Begin<T>(Future<T> future) { ... }
}
然后我可以在Async值上编写查询计算,因此表达式变为:
from x in Async.Begin(Foo.Bar())
...
其中x现在属于未来类型,我可以任意强制或推迟期货和承诺。 感谢大家的建议。 Visual Studio中内置的查询表达式转换器会很好,以防MS的任何人正在阅读它。 ;-)     

要回复问题请先登录注册