使用Linq和继承绑定到对象的通用方法

时间:2012-06-25 10:26:16

标签: c# linq c#-4.0

我正在努力解决如何执行以下操作的问题:

我有几个方法返回不同的强类型IEnumerable对象。 这些强类型类共享一个公共基类,它公开我想要在Linq选择器中访问的属性。

然而,我似乎无法让这个工作。如果我只是在方法中传递基类型,那么在绑定IEnumerable时会出现错误,因为派生类中的可用属性不可用。

如果我尝试传递该类型,那么因为Linq表达式不知道类型我无法访问我的Linq表达式中需要的属性。

我需要以某种方式告诉Linq表达式我的IEnumerable类型是从我的基类派生的。 以下是我正在尝试做的一个例子:

private IEnumerable<MyStronglyTypedResultSet> GetReportDetails()
{
  // this returns the IEnumerable of the derived type
}

public class MyBaseClass
{
    public Guid UserId {get; set;}
    public string OfficeName {get; set;}
}

public class MyStronglyTypedResultSet : MyBaseClass
{
   public string FullName {get; set;}
   public int Age {get; set;}
}

public void MyProblemMethod<T>(IEnumerable<T> allData, string officeToFind)
{
    // How do I tell Linq that my <T> type is derived from 'MyBaseClass' so I can access the 'OfficeName' property?

    IEnumerable<T> myData = allData.Where(c => c.OfficeName .ToLower().Equals(officeToFind.ToLower()));
    MyUsefulObject.DataSource= myData; // This needs to have access to the properties in 'MyStronglyTypedResultSet' 
    MyUsefulObject.DataaBind();
}

2 个答案:

答案 0 :(得分:2)

您可以使用OfType扩展程序。

public void MyProblemMethod<T>(IEnumerable<T> allData, string officeToFind)
{
    // How do I tell Linq that my <T> type is derived from 'MyBaseClass' so I can access the 'OfficeName' property?

    IEnumerable<T> myData = allData.OfType<MyBaseClass>.Where(c => c.OfficeName .ToLower().Equals(officeToFind.ToLower()));
    MyUsefulObject.DataSource= myData;
    MyUsefulObject.DataaBind();
}

答案 1 :(得分:1)

更改您的方法,如下所示

public void MyProblemMethod<T>(IEnumerable<T> allData, string officeToFind) where T : MyBaseClass
{
    // How do I tell Linq that my <T> type is derived from 'MyBaseClass' so I can access the 'OfficeName' property?

    IEnumerable<T> myData = allData.Where(c => c.OfficeName .ToLower().Equals(officeToFind.ToLower()));
    MyUsefulObject.DataSource= myData; // This needs to have access to the properties in 'MyStronglyTypedResultSet' 
    MyUsefulObject.DataaBind();
}