IQueryable OfType où T est un type à l’exécution

Je dois pouvoir obtenir quelque chose de semblable au suivant pour travailler:

Type type = ??? // something decided at runtime with .GetType or typeof; object[] entityList = context.Resources.OfType().ToList(); 

Est-ce possible? Je suis capable d’utiliser .NET 4 si quelque chose de nouveau permet cela.

Vous pouvez l’appeler par reflection:

 MethodInfo method = typeof(Queryable).GetMethod("OfType"); MethodInfo generic = method.MakeGenericMethod(new Type[]{ type }); // Use .NET 4 covariance var result = (IEnumerable) generic.Invoke (null, new object[] { context.Resources }); object[] array = result.ToArray(); 

Une alternative serait d’écrire votre propre méthode générique OfTypeAndToArray pour en faire les deux bits, mais ce qui précède devrait fonctionner.

On dirait que vous aurez besoin d’utiliser Reflection ici …

 public static IEnumerable DyamicOfType( this IQueryable input, Type type) { var ofType = typeof(Queryable).GetMethod("OfType", BindingFlags.Static | BindingFlags.Public); var ofTypeT = ofType.MakeGenericMethod(type); return (IEnumerable) ofTypeT.Invoke(null, new object[] { input }); } Type type = // ...; var entityList = context.Resources.DynamicOfType(type).ToList(); 

Purement sur votre question à utiliser “génériques”, non ce n’est pas possible.

Les génériques sont une fonctionnalité de compilation, et non une découverte à l’exécution. Pour l’exécution, vous devez utiliser Reflection ou Dynamic.

qu’en est-il de …

  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 })); } 

Une solution pour gérer plusieurs types est

  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();