如何转换Expression <func <baseclass,bool =“”>&gt;表达式<func <inheritedclass,bool =“”>&gt;?</func <inheritedclass,> </func <baseclass,>

时间:2013-10-28 05:46:43

标签: c# inheritance expression

假设我有一个基类和继承的类

public class BaseClass
{
    public String SystemName { get; set; }
    public String UserName { get; set; }
}

internal class InheritedClass : BaseClass
{
    public Guid Id { get; set; }        
}

基类上的某些表达式从外部传递给我的模块(从那里看不到继承的类)

Expression<Func<BaseClass, bool>>

它描述了一些过滤逻辑,例如

Expression<Func<BaseClass, bool>> filter = x => x.SystemName.StartsWith("ABC") && x.UserName != ""

但在我的模块中我需要使用

Expression<Func<InheritedClass, bool>>

因为我将此过滤器应用于 IQueryable ,就像那样

IQueryable<InheritedClass> filteredItems = Items.Where(filter);

继承类具有基类的所有属性 - 所以我不太经验的头脑假设转换是可能的:)

有没有办法将传递的表达式转换为我需要的?

谢谢。

1 个答案:

答案 0 :(得分:0)

使用此实用程序类

public static class Utility
{
    //public static IEnumerable<TTarget> Where<TSource, TTarget>(this IEnumerable<TSource> source, Expression<Func<TSource, bool>> predicate) where TTarget : class, TSource
    //{
    //     return source.Where(obj => obj is TTarget).Where(predicate.Compile()).Select(obj => obj as TTarget);
    //}

    public static IQueryable<TTarget> Where<TSource, TTarget>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) where TTarget : class, TSource
    {
        return source.Where(obj => obj is TTarget).Where(predicate).Select(obj => obj as TTarget);
    }
}

示例是这样的, 超级和子类如

class Person
{
    public String Name { get; set; }
    public ushort Age { get; set; }
}

class Student : Person
{
    public String StudentId { get; set; }
}

class Teacher : Person
{
    public String TeacherId { get; set; }
}

使用该实用程序并测试它

            /*List of Persons*/
            List<Person> persons = new List<Person>()
                                                          {
                                                              new Student(){StudentId = "Std-01", Name = "Roy", Age = 24},
                                                              new Student(){StudentId = "Std-02", Name = "Jhon", Age = 25},
                                                              new Teacher(){TeacherId = "Tch-01", Name = "Roy", Age = 24},
                                                              new Teacher(){TeacherId = "Tch-02", Name = "Jhon", Age = 25}
                                                          };
            /*predictions*/
            Expression<Func<Person, bool>> prediction = x => x.Name.Contains("o");


            /*Use the utility*/
                                                                    /*Get Teacher from Persons*/
            IQueryable<Teacher> filteredItems = persons.AsQueryable().Where<Person, Teacher>(prediction);
            List<Teacher> result = filteredItems.ToList();

结果我们将通过TeacherId =“Tch-01”和“Tch-02”获得老师

虽然我使用IEnumerable而不是IQueryable,但希望它会有所帮助