Métodos de extensão que não estão funcionando para uma interface
-
01-07-2019 - |
Pergunta
Inspirado na loja do MVC, o projeto mais recente em que estou trabalhando é usar métodos de extensão no iQueryable para filtrar os resultados.
Eu tenho essa interface;
IPrimaryKey
{
int ID { get; }
}
E eu tenho este método de extensão
public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
return source(obj => obj.ID == id);
}
Digamos que eu tenho uma aula, SimpleObj, que implementa o iPrimaryKey. Quando eu tenho um iQueryabj, o método getById não existe, a menos que eu seja explicitamente lançado como um iQueryable do iPrimaryKey, o que é menos do que o ideal.
Estou perdendo alguma coisa aqui?
Solução
Funciona, quando feito certo. A solução da CFEDUKE funciona. No entanto, você não precisa fazer o IPrimaryKey
Interface genérica, de fato, você não precisa alterar sua definição original:
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
return source(obj => obj.ID == id);
}
Outras dicas
Editar: KonradA solução é melhor porque é muito mais simples. A solução abaixo funciona, mas é necessária apenas em situações semelhantes ao ObjectDataSource, onde um método de classe é recuperado através da reflexão sem aumentar a hierarquia da herança. Obviamente, isso não está acontecendo aqui.
Isso é possível, tive que implementar um padrão semelhante quando projetei uma solução de estrutura de entidade personalizada para trabalhar com o 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; }
}
Trecho 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);
Isso não pode funcionar devido ao fato de que os genéricos não têm a capacidade de seguir padrões de herança. ou seja. IQueyableu003CSimpleObj> não está na árvore de herança de iQueryableu003CIPrimaryKey>