views:

581

answers:

4

I have recreated the Predicatebuilder class in a seperate C# project and I'm trying to use it in a VB.NET project but I keep getting the following error:

Overload resolution failed because no accessible 'Or' accepts this number of arguments.

when I use it like so:

Dim predicate = PredicateBuilder.False(Of t_Quote)()
predicate = predicate.Or(Function(q) q.iQuoteType = iQuoteType)

The relivant project is referenced, I'm using the correct imports statement and it all compiles without any errors.

Any idea where I'm going wrong?

Here is the PredicateBuilder class in C# I'm using:

public static class PredicateBuilder { public static Expression> True() { return f => true; } public static Expression> False() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this

Expression> expr1, Expression> expr2) { var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); return Expression.Lambda> (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); }

    public static Expression<Func<T, bool>> And<T>(this

Expression> expr1, Expression> expr2) { var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); return Expression.Lambda> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); } }

A: 

It works for me:

Dim predicate = PredicateBuilder.False(Of Integer)()
predicate = predicate.Or(Function(q) q Mod 2 = 0)

(I don't have your t_Quote type)

Also, it's horrible practice to have a type name like t_Quote. That should be called Quote; Hungarian notation and underscores are both frowned upon in C# names.

SLaks
...as well as VB.NET names.
Robert Harvey
I accept your comment on the naming convention (not my choice!). The t_Quote type is a linq to sql class does that information help with this issue?
rollercoast
Not that I can think of
SLaks
A: 

Here's the code that works for me in VB.NET, as I also tweaked this class to run in VB.NET...

Imports System.Linq.Expressions

Public Module PredicateBuilder
    Public Function [True](Of T)() As Expression(Of Func(Of T, Boolean))
        Return Function(f) True
    End Function

    Public Function [False](Of T)() As Expression(Of Func(Of T, Boolean))
        Return Function(f) False
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function [Or](Of T)(ByVal expr1 As Expression(Of Func(Of T, Boolean)), ByVal expr2 As Expression(Of Func(Of T, Boolean))) As Expression(Of Func(Of T, Boolean))
        Dim invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast(Of Expression)())
        Return Expression.Lambda(Of Func(Of T, Boolean))(Expression.[Or](expr1.Body, invokedExpr), expr1.Parameters)
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function [And](Of T)(ByVal expr1 As Expression(Of Func(Of T, Boolean)), ByVal expr2 As Expression(Of Func(Of T, Boolean))) As Expression(Of Func(Of T, Boolean))
        Dim invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast(Of Expression)())
        Return Expression.Lambda(Of Func(Of T, Boolean))(Expression.[And](expr1.Body, invokedExpr), expr1.Parameters)
    End Function
End Module

And here's how I use it:

Dim pred = PredicateBuilder.True(Of MyClass)()

pred = pred.And(Function(m As MyClass) m.SomeProperty = someValue)
pred = pred.Or(Function(m As MyClass) m.SomeProperty = someValue)
routeNpingme
I tried this VB.NET version and got the same error.
rollercoast
A: 

One thing to bear in mind, though it may not solve your particular issue, is case-sensitivity when working with cross-language solutions.

C# and the CLR itself are case-sensitive; VB.NET is not. Depending on which way you're consuming the library, an exception may be thrown because the case does not match (and therefore fails to resolve to a known type).

This can happen if you think you've consistently declared your namespace names, but one class has the namespace declared with one character in upper case. This is very easy to do in Visual Basic, but to VB.NET, they all look like they've compiled down to a single, cohesive namespace. As far as the CLR is concerned though, they are two distinct namespaces.

I've run into this issue before, and it was a very elusive bug to track down.

I know you're consuming a C# project from VB.NET, but keep an eye out for those types of issues.

Mike Hofer
+2  A: 

Solved the issue. It was because Option Infer was set to Off. As soon as I set it to On the correct type was infered and it all worked as it should.

rollercoast
Make sure you set this as the accepted answer, as it's useful information for others to know!
Mike Hofer