Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do lambda expressions in VB differ from C#?

Tags:

c#

vb.net

lambda

I just came across a bug in NHibernate which happens to already be raised: https://nhibernate.jira.com/browse/NH-2763

I'm not sure if this applies to anything else other than enums but when using a Lambda from VB, it looks different to the same Lambda from C#.

C#:

Where(x => x.Status == EmployeeStatus.Active)

VB

Where(Function(x) x.Status = EmployeeStatus.Active)

They are the same as far as I'm aware? (My VB isn't great)

If I put a break point on the same line of code, where the above code is passed into. In C# I get:

C# version

On the same line when VB version is passed in, I get:

VB version

Is this something I'm doing wrong? Is the result's the same, just displayed different between C#/VB?

Edit: Ok so they are displayed different, but they can't be the same because NHibernate cannot handle it. The C# version is handled perfectly fine by NHibernate, the VB version resolves in the following exception being thrown:

Exception

The NHibernate StackTrace:

   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

So something must be different between the two?

Edit 2:

For Jonathan. This is the method where the expression is used:

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;
}
like image 618
Phill Avatar asked Jul 19 '11 06:07

Phill


1 Answers

The difference you are seeing has nothing to do with lambdas; it is simply a difference in the semantics of the languages. VB is emitting calls to functions that by default throw exceptions if an integer overflows (hence the Checked part of the name).

By default the C# compiler does not emit the "checked" version of functions, and apparently NHibernate is developed by C# users, so it doesn't seem to recognize the "checked" functions.

If you go to the Compile options for your project and click on Advanced Compile Options, you can check the "Remove integer overflow checks" box so that VB has the default C# behavior and you shouldn't get that error anymore:

Screenshot of dialog showing option

like image 53
Gabe Avatar answered Sep 24 '22 01:09

Gabe