我需要能够获得类似以下内容的工作:
Type type = ??? // something decided at runtime with .GetType or typeof;
object[] entityList = context.Resources.OfType<type>().ToList();
这可能吗?如果有任何新内容允许,我可以使用.NET 4。
答案 0 :(得分:37)
你可以通过反思来调用它:
MethodInfo method = typeof(Queryable).GetMethod("OfType");
MethodInfo generic = method.MakeGenericMethod(new Type[]{ type });
// Use .NET 4 covariance
var result = (IEnumerable<object>) generic.Invoke
(null, new object[] { context.Resources });
object[] array = result.ToArray();
另一种方法是编写自己的OfTypeAndToArray
泛型方法来完成它的两个部分,但上面的方法应该可行。
答案 1 :(得分:8)
看起来你需要在这里使用Reflection ......
public static IEnumerable<object> DyamicOfType<T>(
this IQueryable<T> input, Type type)
{
var ofType = typeof(Queryable).GetMethod("OfType",
BindingFlags.Static | BindingFlags.Public);
var ofTypeT = ofType.MakeGenericMethod(type);
return (IEnumerable<object>) ofTypeT.Invoke(null, new object[] { input });
}
Type type = // ...;
var entityList = context.Resources.DynamicOfType(type).ToList();
答案 2 :(得分:1)
怎么样......
public static IList OfTypeToList(this IEnumerable source, Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
return
(IList) Activator.CreateInstance(
typeof(List<>)
.MakeGenericType(type),
typeof(System.Linq.Enumerable)
.GetMethod(nameof(System.Linq.Enumerable.OfType),
BindingFlags.Static | BindingFlags.Public)
.MakeGenericMethod(type)
.Invoke(null, new object[] { source }));
}
答案 3 :(得分:0)
纯粹在你的问题上使用“泛型”,不,这是不可能的。
Generics是一个编译时功能,而不是运行时发现。对于运行时,您需要使用Reflection或Dynamic。
答案 4 :(得分:0)
处理多种类型的解决方案是
public static IQueryable<TEntity> OfTypes<TEntity>(this DbSet<TEntity> query, IEnumerable<Type> types ) where TEntity : class
{
if( types.Count() == 0 ) return query;
var lambda = GetOfOnlyTypesPredicate( typeof(TEntity), types.ToArray() );
return query.OfType<TEntity>().Where( lambda as Expression<Func<TEntity,bool>>);
}
public static LambdaExpression GetOfOnlyTypesPredicate( Type baseType, Type[] allowed )
{
ParameterExpression param = Expression.Parameter( baseType, "typeonlyParam" );
Expression merged = Expression.TypeIs( param, allowed[0] );
for( int i = 1; i < allowed.Length; i++ )
merged = Expression.OrElse( merged, Expression.TypeIs( param, allowed[i] ));
return Expression.Lambda( merged, param );
答案 5 :(得分:0)
基于@ Jon Skeet的answer,这是LINQ扩展方法:
public static class QueryableExtensions
{
public static IQueryable<TSource> OfType<TSource>(this IQueryable<TSource> queryable,
Type runtimeType)
{
var method = typeof(Queryable).GetMethod(nameof(Queryable.OfType));
var generic = method.MakeGenericMethod(new[] { runtimeType });
return (IQueryable<TSource>)generic.Invoke(null, new[] { queryable });
}
}
答案 6 :(得分:0)
这对我有用...
for(int i = 0; i < P; i++){
for(int j = P-1; j >= 0; j--){
for(int k = 0; k < D; k++){}
for(int z = 0; z < D; z++){}
}}
答案 7 :(得分:-1)
object[] entityList = context.Resources
.Where(t=> t.GetType() == type)
.ToArray();