扩展方法不适用于接口
问题描述:
受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的IQueryable时,GetByID方法不存在,除非我明确地将其转换为IPrimaryKey的IQueryable,这并不理想。
我在这里错过了什么吗?
答
它的工作原理,如果做得对。 cfeduke的解决方案起作用。不过,你不必让IPrimaryKey
接口通用,其实,你不必改变你的原始定义:
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
return source(obj => obj.ID == id);
}
答
由于泛型没有遵循继承模式的能力,因此无法工作。即。 IQueryable的<SimpleObj>不是IQueryable的<IPrimaryKey>
答
编辑的继承树: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);
优秀的 - 我接受的原答复。我明天会试试这个。谢谢你们。 – Kirschstein 2008-09-17 17:25:32