Использование PredicateBuilder с VB.NET
Я воссоздал класс Predicatebuilder в отдельном проекте C# и пытаюсь использовать его в проекте VB.NET, но продолжаю получать следующую ошибку:
Не удалось разрешить перегрузку, поскольку ни одно доступное "ИЛИ" не принимает это количество аргументов.
когда я использую это так:
Dim predicate = PredicateBuilder.False(Of t_Quote)()
predicate = predicate.Or(Function(q) q.iQuoteType = iQuoteType)
Ссылка на релевантный проект, я использую правильный оператор импорта, и все это компилируется без каких-либо ошибок.
Есть идеи, где я иду не так?
Вот класс PredicateBuilder в C#, который я использую:
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
Выражение> expr1, Выражение> 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
Выражение> expr1, Выражение> expr2) { var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); return Expression.Lambda> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); } }
4 ответа
Решил вопрос. Это было потому, что Option Infer был выключен. Как только я установил значение On, был введен правильный тип, и все заработало как надо.
Вот код, который работает для меня в 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
И вот как я это использую:
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)
Следует иметь в виду, что, хотя это может и не решить вашу конкретную проблему, это чувствительность к регистру при работе с мультиязычными решениями.
C# и сам CLR чувствительны к регистру; VB.NET нет. В зависимости от того, каким образом вы используете библиотеку, может возникать исключение, потому что регистр не совпадает (и, следовательно, не удается разрешить до известного типа).
Это может произойти, если вы думаете, что последовательно объявляли имена своих пространств имен, но у одного класса пространство имен объявлено с одним символом в верхнем регистре. Это очень легко сделать в Visual Basic, но для VB.NET все они выглядят так, как будто они скомпилированы в одно связное пространство имен. Что касается CLR, то это два разных пространства имен.
Я сталкивался с этой проблемой прежде, и это была очень неуловимая ошибка, чтобы выследить.
Я знаю, что вы используете проект C# из VB.NET, но следите за этими типами проблем.
Меня устраивает:
Dim predicate = PredicateBuilder.False(Of Integer)()
predicate = predicate.Or(Function(q) q Mod 2 = 0)
(У меня нет твоего t_Quote
тип)
Кроме того, это ужасная практика иметь имя типа, как t_Quote
, Это должно быть названо Quote
; Венгерская нотация и подчеркивание не одобряются в именах C#.