代码之家  ›  专栏  ›  技术社区  ›  Kirschstein

扩展方法不适用于接口

  •  6
  • Kirschstein  · 技术社区  · 17 年前

    受MVC店面的启发,我正在进行的最新项目是使用iQueryable上的扩展方法来过滤结果。

    我有这个接口;

    IPrimaryKey
    {
      int ID { get; }
    }
    

    我有这个扩展方法

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

    假设我有一个类simpleobj,它实现了IPrimaryKey。当我有一个simpleobj的iquerieble时,getbyid方法不存在,除非我明确地将其转换为iprimarykey的iquerieble,这不太理想。

    我是不是错过了什么?

    3 回复  |  直到 17 年前
        1
  •  13
  •   Konrad Rudolph    17 年前

    如果做得好,它就会起作用。cfeduke的解决方案有效。但是,你不必 IPrimaryKey 接口通用,实际上,您根本不需要更改原始定义:

    public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
    {
        return source(obj => obj.ID == id);
    }
    
        2
  •  4
  •   Community Mohan Dere    8 年前

    编辑: Konrad 的解决方案更好,因为它要简单得多。下面的解决方案可以工作,但仅在类似于ObjectDatasource的情况下才是必需的,在这种情况下,通过反射检索类的方法,而不需要遍历继承层次结构。很明显这不是在这里发生的。

    这是可能的,我在设计用于处理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; }
    }
    

    使用片段:

    var people = new List<Person>
    {
        new Person { Id = 1 },
        new Person { Id = 2 },
        new Person { Id = 3 }
    };
    
    var personOne = people.AsQueryable().GetById(1);
    
        3
  •  2
  •   Garry Shutler    17 年前

    由于泛型没有遵循继承模式的能力,因此这无法工作。例如,iqueryable<SimpleObj>不在iqueryable<iPrimaryKey>的继承树中。