我有两个扩展名:
public static IQueryable<T> Existing<T>(this IQueryable<T> qry)
where T : class, IDeletable
{
return qry.Where(...);
}
public static IEnumerable<T> Existing<T>(this IEnumerable<T> qry)
where T : class, IDeletable
{
return qry.Where(...);
}
如何将这两种方法合并为一种方法?我尝试了以下方法:
public static TU Existing<TU, T>(this TU qry)
where TU : class, IQueryable<T>, IEnumerable<T>
where T : class, IDeletable
{
return (TU)qry.Where(...);
}
但这不起作用,因为无法正确推断类型(因为IQueryable继承自IEnumerable,我猜)。此外,T
并不总是IQueryable
,这似乎也是一个问题(问题:如果我在where子句中指定多个接口,那么不是以析取方式匹配的那些接口吗?)。在之前的情况下,如果适用IQuerable
,则使用IEnumerable
或{{1}}。我怎么能绕过这个?
答案 0 :(得分:4)
您的尝试始终将其限制为IQueryable<T>
实施。我假设你真的希望它适用于进程内查询和进程外查询。假设Where
子句中的“...”是一个lambda表达式,你需要注意即使你在两个方法中都有相同的代码,编译器也会以非常不同的方式处理它们 - 因为它会已经应用了重载决策来确定要使用的Where
实现。
我强烈建议你保留两个单独的重载原样。
答案 1 :(得分:2)
public static IQueryable<T> Existing<T>(this IEnumerable<T> qry) where T : class, IDeletable
{
return qry.Where(/*...*/).AsQueryable();
}
在已经可查询的内容上调用AsQueryable
将不会执行任何操作。另外,IQueryable继承自IEnumerable,所以首先:你可以将IQueryable传递给这个方法,第二个:结果实际上是IEnumerable和IQueryable。