为什么VB中的lambda表达式与C#不同?
我刚刚在NHibernate中遇到一个bug,它碰巧已经被提出: 我不确定这是否适用于枚举以外的任何其他对象,但当使用VB中的Lambda时,它看起来与C#中的相同Lambda不同 C#: VB 就我所知他们是一样的?(我的VB不是很好) 如果我在同一行代码上放一个断点,上面的代码被传递到同一行代码中。在C#中,我得到: 在同一行中,当传入VB版本时,我得到: 这是不是我做错了什么?结果是否相同,只是在C#/VB之间显示不同 编辑: 好的,所以它们显示不同,但它们不能相同,因为NHibernate无法处理它。NHibernate对C#版本的处理非常好,VB版本在引发以下异常时解决: NHibernate堆栈跟踪:为什么VB中的lambda表达式与C#不同?,c#,vb.net,lambda,C#,Vb.net,Lambda,我刚刚在NHibernate中遇到一个bug,它碰巧已经被提出: 我不确定这是否适用于枚举以外的任何其他对象,但当使用VB中的Lambda时,它看起来与C#中的相同Lambda不同 C#: VB 就我所知他们是一样的?(我的VB不是很好) 如果我在同一行代码上放一个断点,上面的代码被传递到同一行代码中。在C#中,我得到: 在同一行中,当传入VB版本时,我得到: 这是不是我做错了什么?结果是否相同,只是在C#/VB之间显示不同 编辑: 好的,所以它们显示不同,但它们不能相同,因为NHiber
at NHibernate.Impl.ExpressionProcessor.FindMemberExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 168
at NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(Expression left, Expression right, ExpressionType nodeType) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 323
at NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(BinaryExpression be) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 316
at NHibernate.Impl.ExpressionProcessor.ProcessBinaryExpression(BinaryExpression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 418
at NHibernate.Impl.ExpressionProcessor.ProcessExpression(Expression expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 486
at NHibernate.Impl.ExpressionProcessor.ProcessExpression[T](Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line 504
at NHibernate.Criterion.QueryOver`2.Add(Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 635
at NHibernate.Criterion.QueryOver`2.NHibernate.IQueryOver<TRoot,TSubType>.Where(Expression`1 expression) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line 686
at *removed*.EmployeeRepository.GetByEntityId(Int64 entityId, Expression`1 basicCriteria) in D:\*removed*\EmployeeRepository.cs:line 76
位于d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.cs中的NHibernate.Impl.ExpressionProcessor.FindMemberExpression(表达式表达式表达式):第168行
位于d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.ProcessSimpleExpression(表达式左、表达式右、表达式类型节点类型)中的NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(表达式左、表达式右、表达式类型节点类型):第323行
在d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.ProcessSimpleExpression(二进制表达式be)中的NHibernate.Impl.ExpressionProcessor.ProcessSimpleExpression(二进制表达式be):第316行
在d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.cs中的NHibernate.Impl.ExpressionProcessor.ProcessBinaryExpression(BinaryExpression表达式)处:第418行
位于d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.cs中的NHibernate.Impl.ExpressionProcessor.ProcessExpression(表达式表达式表达式):第486行
在d:\CSharp\NH\NH\NHibernate\src\NHibernate\Impl\ExpressionProcessor.cs中的NHibernate.Impl.ExpressionProcessor.ProcessExpression[T](表达式'1 Expression)处:第504行
在NHibernate.criteria.QueryOver`2.Add(表达式`1表达式)中的d:\CSharp\NH\NH\NHibernate\src\NHibernate\criteria\QueryOver.cs:第635行
在d:\CSharp\NH\NH\NH\NHibernate\src\NHibernate\criteria\QueryOver`2.NHibernate.IQueryOver.Where(表达式`1 Expression)中的NHibernate.criteria.QueryOver`2.NHibernate.IQueryOver.Where(表达式`1 Expression):第686行
在D:\*removed*\EmployeeRepository.cs:第76行中的*removed*.EmployeeRepository.GetByEntityId(Int64 entityId,表达式'1 basicCriteria)处
那么这两者之间一定有什么不同
编辑2:
乔纳森。这是使用表达式的方法:
public IEnumerable<Employee> GetByEntityId(long entityId, Expression<Func<Employee, bool>> basicCriteria)
{
IEnumerable<Employee> result;
using (var tx = Session.BeginTransaction())
{
var employeeQuery = Session.QueryOver<Employee>()
.Where(x => x.EntityId == entityId);
if (basicCriteria != null)
employeeQuery = employeeQuery.Where(basicCriteria);
result = employeeQuery.List();
tx.Commit();
}
return result;
}
public IEnumerable GetByEntityId(长entityId,表达式基本准则)
{
可数结果;
使用(var tx=Session.BeginTransaction())
{
var employeeQuery=Session.QueryOver()
。其中(x=>x.EntityId==EntityId);
if(基本准则!=null)
employeeQuery=employeeQuery.Where(基本标准);
结果=employeeQuery.List();
tx.Commit();
}
返回结果;
}
是的,只是显示的不同而已。
你没有做错什么。VB内联方法有另一种语法和IDE集成您看到的差异与lambdas无关;这只是语言语义上的差异。VB正在向函数发出调用,默认情况下,如果整数溢出,这些函数会抛出异常(因此名称的
部分被选中)
默认情况下,C#编译器不会发出“已检查”版本的函数,而且显然NHibernate是由C#用户开发的,因此它似乎无法识别“已检查”的函数
如果您转到项目的编译选项并单击高级编译选项,您可以选中“删除整数溢出检查”框,以便VB具有默认的C#行为,您不应该再出现该错误:
带有\uu DisplayClass
的部分表示编译器创建了一个闭包。这意味着调试器中的表达式不是您显示的表达式,而是类似的表达式
var status = EmployeeStatus.Active;
Expression<Func<Employee, bool>> expr = x => x.Status == status;
编辑:如果找不到其他选项,作为最后手段,您可以使用Convert
而不是ConvertChecked
将VB.NET生成的表达式重写为表单:
类未选中的查看器
继承ExpressionVisitor
受保护的覆盖函数访问权限(_
作为一元表达式的节点_
)作为表达
如果node.NodeType=ExpressionType.ConvertChecked
node=表达式.Convert(node.Operand,node.Type,node.Method)
如果结束
返回MyBase.visiturary(节点)
端函数
末级
unchechedVisitor.Visit(expr)
然后返回expr
,所有ConvertChecked
实例替换为Convert
哇,lambdas的VB.net调试真是太棒了@Mehrdad/@fantasticfix-我已经更新了我的问题,将异常包括在内。VB和C版本之间一定有区别。对不起。。。bool>>basicCriteria做什么?@Jonathan-添加了使用“basicCriteria”的方法。它只不过是提供对结果的轻微过滤。在本例中,按状态筛选员工。@Petr,这与C#相同。不同的IDE集成肯定不是生成表达式中存在差异的原因。先生,您是一个传奇:未经检查,它工作正常。不幸的是,关闭它让我感觉不舒服,它是一个有10年历史的代码库。因此必须编写一些方法重载:(@Phill:你知道你有没有最新版本的NHibernate吗?你可能遇到了一个已经修复的错误。我正在使用3.1,Fluent NHibernate网站还没有用3.2更新它的发行版,我不想编译我自己的版本。但是下一个Fluent发行版出来的那一刻,我会更新并重新测试。明天会给svick的代码一个测试当我进办公室的时候。谢谢你的解释
public IEnumerable<Employee> GetByEntityId(long entityId, Expression<Func<Employee, bool>> basicCriteria)
{
IEnumerable<Employee> result;
using (var tx = Session.BeginTransaction())
{
var employeeQuery = Session.QueryOver<Employee>()
.Where(x => x.EntityId == entityId);
if (basicCriteria != null)
employeeQuery = employeeQuery.Where(basicCriteria);
result = employeeQuery.List();
tx.Commit();
}
return result;
}
var status = EmployeeStatus.Active;
Expression<Func<Employee, bool>> expr = x => x.Status == status;
checked
{
Expression<Func<Employee, bool>> expr = x => x.Status == EmployeeStatus.Active;
}