通用扩展方法

时间:2009-05-07 16:52:59

标签: methods generics

我正在根据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,所以你怎么解决这个问题?

2 个答案:

答案 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属性的类型,如果存在,则获取值。