2012-06-29 2 views
1

У меня есть несколько классов, наследующих от базового классаНаследование и полиморфизм в LINQ Лямбдах

Public MustInherit Class BaseClass 
    Public Property Name as String 
End Class 

Public MustInherit Class ClassA 
    Inherits BaseClass 
    Public Property Something As String 
End Class 

Public MustInherit Class ClassB 
    Inherits BaseClass 
    Public Property SomethingElse As String 
End Class 

Я хочу, чтобы иметь возможность использовать одно выражение для запроса несколько списков объектов, все они наследуют из того же базового класса

Public Function DoStuff(Expression as System.Linq.Expressions.Expression(Of Func(Of BaseClass, Boolean))) 
    Dim ListA As New List(Of ClassA) ''Populating this elsewhere 
    Dim ListB As New List(Of ClassB) ''and this 

    Dim ResultSetA = ListA.Where(Expression) ''Problems on this line 
    Dim ResultSetB = ListA.Where(Expression) ''and this 
End Function 

так как ClassA и ClassB наследуют от базового класса, и так как запрос LINQ против базового класса, он должен работы. Expression может относиться только к свойствам базового класса, которые гарантированно будут присутствовать на оба производных классах, но я получаю следующее сообщение об ошибке набрав во время компиляции:

Value of type 'System.Linq.Expressions.Expression(Of System.Func(Of BaseClass, Boolean))' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of ClassA, Boolean))' 

Есть ли способ, я могу добавить увеличивающееся преобразование (или что-то подобное), чтобы позволить этому работать?

или мне нужно предоставить один и тот же запрос несколько раз для каждого производного класса?

+0

Я думаю, что вам нужно Cast Linq до того, где, но я не знаю синтаксис VB. Я предполагаю, что это может быть. Cast (Of BaseClass)? – podiluska

+0

Вы хотели бы передать в 'Func' вместо' Expression'? – Henry

+0

@HenryP На самом деле, нет. Я упростил приведенный выше пример, поскольку я фактически выполняю его для сущностей в Db, списки - это репозитории, и у меня есть некоторые другие вещи, которые динамически изменяют дерево выражений. Предложенный Baseclass является общей базой «Job», которую все сущности, представляющие задания, наследуют от – Basic

ответ

3

Вы должны AsQueryable() список (C# синтаксис ниже)

var ResultA = lista.AsQueryable().Where(expression); 

Вы можете затем отливали результаты обратно к исходным типам, если вам нужно

foreach (var x in ResultA) 
{ 
     Response.Write(((ClassA)x).Something); 
} 
+0

Хороший улов - на самом деле, сделав его' IQueryable' и используя @ HenryP's предложение компиляции запроса, я могу сделать это без литья ... 'ListA.AsQueryable.Where (Expression.Compile)'. Благодаря! – Basic