从对象列表创建运行时已知类型列表并调用泛型方法
Create list of runtime-known type from object list and call generic method
我记忆中有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
在运行时执行它。
在运行时,我必须为 runtime-known 类型的某些 Enumerable<T>
动态调用此方法。
但是,不管我做了什么,它都不起作用。 model.GetType()
总是 Object
或抛出异常。
Object of type
'System.Linq.Enumerable+WhereSelectArrayIterator2[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;
}
并使用反射直接调用此方法!
我记忆中有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
在运行时执行它。
在运行时,我必须为 runtime-known 类型的某些 Enumerable<T>
动态调用此方法。
但是,不管我做了什么,它都不起作用。 model.GetType()
总是 Object
或抛出异常。
Object of type 'System.Linq.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;
}
并使用反射直接调用此方法!