IQueryable OfType 其中T是运行时类型
我需要能够得到类似以下的东西才能工作:
Type type = ??? // something decided at runtime with .GetType or typeof; object[] entityList = context.Resources.OfType().ToList();
这可能吗? 如果有任何新内容允许,我可以使用.NET 4。
你可以通过反思来调用它:
MethodInfo method = typeof(Queryable).GetMethod("OfType"); MethodInfo generic = method.MakeGenericMethod(new Type[]{ type }); // Use .NET 4 covariance var result = (IEnumerable
另一种方法是编写自己的OfTypeAndToArray
generics方法来完成它的两个位,但上面的方法应该可行。
看起来你需要在这里使用Reflection …
public static IEnumerable
纯粹在你的问题上使用“generics”,不,这是不可能的。
generics是编译时function,而不是运行时发现。 对于运行时,您需要使用Reflection或Dynamic。
关于什么 …
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 })); }
处理多种类型的解决方案是
public static IQueryable OfTypes (this DbSet query, IEnumerable types ) where TEntity : class { if( types.Count() == 0 ) return query; var lambda = GetOfOnlyTypesPredicate( typeof(TEntity), types.ToArray() ); return query.OfType().Where( lambda as Expression>); } 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 );
object[] entityList = context.Resources .Where(t=> t.GetType() == type) .ToArray();