扩展方法不适用于接口
时间:2020-03-05 18:58:42 来源:igfitidea点击:
受MVC店面的启发,我正在从事的最新项目是使用IQueryable上的扩展方法来过滤结果。
我有这个界面;
IPrimaryKey { int ID { get; } }
而且我有这种扩展方法
public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id) { return source(obj => obj.ID == id); }
假设我有一个实现IPrimaryKey的类SimpleObj。当我有一个SimpleObj的IQueryable时,除非我明确地将其转换为IPrimaryKey的IQueryable,否则不存在GetByID方法,这不理想。
我在这里想念什么吗?
解决方案
回答
由于泛型没有遵循继承模式的能力,因此无法使用。 IE。 IQueryable <SimpleObj>不在IQueryable <IPrimaryKey>的继承树中
回答
编辑:Konrad的解决方案更好,因为它更简单。以下解决方案有效,但仅在类似于ObjectDataSource的情况下才需要,在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);
回答
正确完成后即可正常工作。 cfeduke的解决方案有效。但是,我们不必使IPrimaryKey接口通用,实际上,我们根本不必更改原始定义:
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey { return source(obj => obj.ID == id); }