简体   繁体   English

在VB.NET中使用PredicateBuilder

[英]Using PredicateBuilder with VB.NET

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: 我在一个单独的C#项目中重新创建了Predicatebuilder类,我试图在VB.NET项目中使用它但是我一直收到以下错误:

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. 引用了relivant项目,我正在使用正确的import语句,它都编译没有任何错误。

Any idea where I'm going wrong? 知道我哪里错了吗?

Here is the PredicateBuilder class in C# I'm using: 这是我正在使用的C#中的PredicateBuilder类:

public static class PredicateBuilder { public static Expression> True() { return f => true; public static class PredicateBuilder {public static Expression> True(){return f => true; } public static Expression> False() { return f => false; 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()); Expression> expr1,Expression> expr2){var invokedExpr = Expression.Invoke(expr2,expr1.Parameters.Cast()); return Expression.Lambda> (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); 返回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()); Expression> expr1,Expression> expr2){var invokedExpr = Expression.Invoke(expr2,expr1.Parameters.Cast()); return Expression.Lambda> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); 返回Expression.Lambda>(Expression.AndAlso(expr1.Body,invokedExpr),expr1.Parameters); } } }}

Here's the code that works for me in VB.NET, as I also tweaked this class to run in VB.NET... 这是在VB.NET中适用于我的代码,因为我还调整了这个类在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)

Solved the issue. 解决了这个问题。 It was because Option Infer was set to Off. 这是因为Option Infer设置为Off。 As soon as I set it to On the correct type was infered and it all worked as it should. 一旦我将它设置为On,就会输入正确的类型,并且它都能正常工作。

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; C#和CLR本身区分大小写; VB.NET is not. VB.NET不是。 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. 这在Visual Basic中很容易实现,但对于VB.NET,它们看起来都像是编译成一个单一的,有凝聚力的命名空间。 As far as the CLR is concerned though, they are two distinct namespaces. 就CLR而言,它们是两个不同的命名空间。

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. 我知道你正在使用VB.NET中的C#项目,但要注意这些类型的问题。

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) (我没有你的t_Quote类型)

Also, it's horrible practice to have a type name like t_Quote . 此外,拥有像t_Quote这样的类型名称是一种可怕的做法。 That should be called Quote ; 这应该叫做Quote ; Hungarian notation and underscores are both frowned upon in C# names. 匈牙利的符号和下划线在C#名称中都不受欢迎。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM