简体   繁体   English

如何结合两种通用方法

[英]How to combine two generic methods

I have to two extensions: 我有两个扩展:

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(...);
}

How do I combine those two methods into one method? 如何将这两种方法合并为一种方法? I tried the following: 我尝试了以下方法:

public static TU Existing<TU, T>(this TU qry)
    where TU : class, IQueryable<T>, IEnumerable<T>
    where T : class, IDeletable
{
    return (TU)qry.Where(...);
}

But this doesn't work because the type can't be inferred correctly (because IQueryable inherits from IEnumerable, I guess). 但这是行不通的,因为无法正确推断类型(我想是因为IQueryable继承自IEnumerable)。 Moreover, T isn't always IQueryable , which also seems to be a problem here (question: if I specify multiple interfaces in the where clause, aren't those matched in a disjunctive manner?). 而且, T并不总是IQueryable ,这在这里似乎也是一个问题(问题:如果我在where子句中指定了多个接口,这些接口不是以分离的方式匹配的吗?)。 In the previous case IQuerable was used if it suited or else IEnumerable . 在以前的情况下,如果合适则使用IQuerable ,否则使用IEnumerable How can I circumvent this? 我该如何规避?

Your attempt will always limit it to IQueryable<T> implementations. 您的尝试将始终将其限制为IQueryable<T>实现。 I assume you really want it to work for both in-process queries and out-of-process queries. 我假设您确实希望它同时适用于进程内查询和进程外查询。 Assuming that the "..." in the Where clause is a lambda expression, you need to be aware that even if you have the same code in both methods, the compiler will be handling them very differently - because it will already have applied overload resolution to determine the Where implementation to use. 假设Where子句中的“ ...”是一个lambda表达式,您需要知道,即使两个方法中的代码相同,编译器对它们的处理也将非常不同-因为它已经应用了重载确定使用Where实现的分辨率。

I would strongly advise you to leave the two separate overloads as they are. 我强烈建议您保留两个单独的重载。

public static IQueryable<T> Existing<T>(this IEnumerable<T> qry) where T : class, IDeletable
{
    return qry.Where(/*...*/).AsQueryable();
}

Calling AsQueryable on something that is already queryable will do nothing. 在已经可查询的AsQueryable上调用AsQueryable不会执行任何操作。 Also, IQueryable inherits from IEnumerable, so first: you can pass an IQueryable to this method, and second: the result is actually an IEnumerable as well as an IQueryable. 另外,IQueryable继承自IEnumerable,因此首先:您可以将IQueryable传递给此方法,其次:结果实际上是IEnumerable以及IQueryable。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM