c# - 将 List 转换为 typeof UnderlyingSystemType

标签 c# list inheritance reflection dynamic-linq

我目前正在编写使用 dynamic-linq 的代码,我在使用 List<BaseClass> 时遇到了问题,其中列表实际上包含 Person 的列表类。

当我执行以下代码时,我得到 ParseException :

var list = new List<BaseClass>();

list.Add(new Person
{
  FirstName = "Joe",
  Surname   = "Bloggs"
});

list.Where("FirstName == @0", "Joe");

还有异常(exception):

enter image description here

请参阅BaseClass如下:

public class BaseClass 
{
    public int Id { get; set; }
}

还有Person类:

public class Person : BaseClass
{
   public string FirstName { get; set; }
   public string Surname   { get; set; }
}

我可以通过实现以下代码来克服该错误:

var list = new List<BaseClass>();

list.Add(new Person
{
  FirstName = "Joe",
  Surname   = "Bloggs"
});            

var newList = CreateListOfCorrectType<BaseClass>(list);
newList.Where("FirstName == @0", "Joe");

请参阅CreateListOfCorrectType<T>方法如下:

private IList CreateListOfCorrectType<T>(
         List<T> list) 
{
  if (list.Count == 0)
  {
    return list;
  }

  var typeInfo = list.FirstOrDefault().GetType();

  var correctListType   = typeof(List<>).MakeGenericType(typeInfo.UnderlyingSystemType);
  var listOfCorrectType = (Activator.CreateInstance(correctListType)) as IList;

  list.ForEach(x => listOfCorrectType.Add(x));

  return listOfCorrectType;
}

我的问题是是否使用CreateListOfCorrectType是解决问题的最好方法吗?如果不是,我有什么替代方案来获得 List<BaseClass>到正确的类型。

我希望将其与现有代码一起使用,并更改现有的 List<>类型是不可能的。还有CreateListOfCorrectType方法不知道Person类。

请注意,类名称和变量仅用于演示目的。

更新

下面乐观主义者的回答引导我找到了问题的解决方案,请参阅下面使用的扩展方法:

public static IList ToDerivedListType(this IList list)
    {
        if (list == null || list.Count == 0) 
        {
            return list;
        }

        var type       = list.Cast<object>().FirstOrDefault().GetType();
        var castedList = typeof(Enumerable).GetMethod("Cast", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
                                           .MakeGenericMethod(type)
                                           .Invoke(null, new[] { list });

        return typeof(Enumerable).GetMethod("ToList", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
                                 .MakeGenericMethod(type)
                                 .Invoke(null, new[] { castedList }) as IList;           
    }

System.Linq.Enumerable.CastMakeGenericMethod是关键。

最佳答案

如何使用 OfType linq 方法:

list.OfType<Person>().Where("FirstName == @0", "Joe");

参见https://msdn.microsoft.com/en-us/library/vstudio/bb360913(v=vs.100).aspx

关于c# - 将 List 转换为 typeof UnderlyingSystemType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30893774/

相关文章:

c# - 图表数据绑定(bind)到数据表 - 图表未更新

c# - 在运行时解析成员名称

c# - 具有属性路由的 ASP.NET Web API Controller 在没有路由名称的情况下无法工作

python - 从txt文件Python创建字典

Python,列出二维数组中超出范围的索引

python - TLE 计算列表中指定范围内的元素数量

java - 为什么这段代码打印父类(super class)而不是子类的值

c# - WCF Web 服务返回 json 格式数据

c# - 隐藏继承类的构造函数

java - 使用 JAX-WS Maven 插件 (wsimport) 检查 Web 服务中的异常层次结构