从对象列表中创建运行时已知类型的列表并调用泛型方法

本文关键字:列表 类型 调用 泛型方法 对象 创建 运行时 | 更新日期: 2023-09-27 17:50:42

我在内存中有IEnumerable<object>

我们这样说:

IEnumerable<object>() addedEntities = // ... some Linq-To-Object query

另外,我有一个签名为

的方法:
public static IEnumerable<TSource> FilterByUniqueProp<TSource>
                (this IEnumerable<TSource> query, TSource model)
{
       // Do something according to this type
       var type = model.GetType();
}
如您所见,这是一个扩展方法。所以,我不能动态调用它,我必须使用MethodInfo在运行时执行它。

在运行时,我必须为运行时已知的类型的某些Enumerable<T>动态调用此方法。但是,不管我做什么,它都不起作用。model.GetType()总是Object或者抛出异常。

类型的对象"来。Enumerable+WhereSelectArrayIterator 2[System.Data.Objects.ObjectStateEntry,System.Object]' cannot be converted to type System.Collections.Generic.IEnumerable 1[PersonDetail] .

这是我尝试过的:

 IEnumerable<object>() addedEntities = // ... some Linq-To-Object query
 Type listType = typeof(List<>);
 Type constructed = listType.MakeGenericType(model.GetType());
 dynamic myList = Activator.CreateInstance(constructed);
 myList = addedEntities;
 MethodInfo mesthod = typeof(DynamicLinqExtensions).GetMethod("FilterByUniqueProp");
 MethodInfo genericMethod= mesthod.MakeGenericMethod(model.GetType());
 dynamic sameEntitiesInContext = genericMethod.Invoke(this, new object[] { myList, model });

从对象列表中创建运行时已知类型的列表并调用泛型方法

相当容易:

public static class DynamicLinqExtensions
{
    public static IEnumerable<TSource> FilterByUniqueProp<TSource>
            (this IEnumerable<TSource> query, TSource model)
    {
        // Do something accourding to this type
        var type = typeof(TSource);
        return null;
    }
    public static IEnumerable<TSource> FilterByUniqueProp2<TSource>
            (this IEnumerable<object> query, TSource model)
    {
        // We use Cast<>() to conver the IEnumerable<>
        return query.Cast<TSource>().FilterByUniqueProp<TSource>(model);
    }
}

使用.Cast<> !

使用方式:

// Your data
IEnumerable<object> addedEntities = new object[] { new MyClass(), new MyClass() };
object model = new MyClass();
// The needed code
Type type = model.GetType();
MethodInfo method = typeof(DynamicLinqExtensions)
          .GetMethod("FilterByUniqueProp2")
          .MakeGenericMethod(type);
method.Invoke(null, new object[] { addedEntities, model });

请注意,实际上您可以直接将FilterByUniquePropr的签名更改为:

public static IEnumerable<TSource> FilterByUniqueProp<TSource>
        (this IEnumerable<object> query, TSource model)
{
    var query2 = query.Cast<TSource>();
    var type = typeof(TSource);
    return null;
}

并使用反射直接调用此方法!