我正在根据Rob Connery的店面视频系列和应用这些技术开展这个mvc项目。 在过滤和扩展方法上,我开始重复自己,例如:
public static Sponsor WithID(this IQueryable<Sponsor>qry, int ID)
{
return qry.SingleOrDefault(s => s.ID== ID);
}
public static Keyword WithID(this IQueryable<Keyword>qry,int ID)
{
return qry.SingleOrDefault(s => s.ID== ID);
}
....
为了防止这种情况,我尝试编写这样的通用扩展名:
public static T WithID<T>(this IQueryable<T>qry,int ID)
{
return qry.SingleOrDefault(s=>ID==ID);
}
然而s没有ID,所以你怎么解决这个问题?
答案 0 :(得分:5)
您需要一个声明ID属性的接口,例如
public interface IInt32Identifiable
{
public int ID { get; }
}
然后你可以写:
public static T WithID<T>(this IQueryable<T> source, int id)
where T : IInt32Identifiable
{
return source.SingleOrDefault(s=> s.ID == id);
}
当然,你必须让所有适当的类实现接口 - 但这通常很容易;如果类是设计器生成的,你可能想要使用部分类。
答案 1 :(得分:0)
您需要两种不同的扩展方法。一个用于具有ID的类型,另一个用于不具有ID的类型。您还需要一个所有ID类型实现的接口或抽象基类。否则,编译器将不允许您取消引用ID。
我能想到的唯一其他替代方案是需要反射来查询ID属性的类型,如果存在,则获取值。