Pregunta

Inspirado por la MVC escaparate de la más reciente proyecto en el que estoy trabajando es en el uso de métodos de extensión en IQueryable < t > para filtrar los resultados.

Tengo esta interfaz;

IPrimaryKey
{
  int ID { get; }
}

y tengo este método de extensión

public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
    return source(obj => obj.ID == id);
}

Digamos que tengo una clase, SimpleObj que implementa IPrimaryKey.Cuando tengo un IQueryable de SimpleObj la GetByID método no existe, a menos que yo explicitally fundido como un IQueryable de IPrimaryKey, que es menos que ideal.

Me estoy perdiendo algo aquí?

¿Fue útil?

Solución

Funciona, cuando se hace bien.cfeduke la solución de las obras.Sin embargo, usted no tiene que hacer el IPrimaryKey interfaz genérica, de hecho, usted no tiene que cambiar su definición original del todo:

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
    return source(obj => obj.ID == id);
}

Otros consejos

Editar: Konrad's solución es mejor porque es mucho más sencillo.La siguiente solución funciona, pero sólo es necesario en situaciones similares a ObjectDataSource donde un método de una clase se recupera a través de la reflexión sin tener que caminar hasta la jerarquía de herencia.Obviamente eso no sucede aquí.

Esto es posible, yo he tenido que aplicar un patrón similar cuando he diseñado una entidad personalizada marco de la solución para trabajar con ObjectDataSource:

public interface IPrimaryKey<T> where T : IPrimaryKey<T>
{
    int Id { get; }
}

public static class IPrimaryKeyTExtension
{
     public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T>
     {
         return source.Where(pk => pk.Id == id).SingleOrDefault();
     }
}

public class Person : IPrimaryKey<Person>
{
    public int Id { get; set; }
}

Fragmento de uso:

var people = new List<Person>
{
    new Person { Id = 1 },
    new Person { Id = 2 },
    new Person { Id = 3 }
};

var personOne = people.AsQueryable().GetById(1);

Esto no es posible debido al hecho de que los genéricos no tienen la capacidad de seguir los patrones de herencia.es decir.IQueryable<SimpleObj> no está en el árbol de herencia de IQueryable<IPrimaryKey>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top