Вы можете построить IQueryable<T>
внутри метода, а затем сделать метод универсальным. Если вы сделаете это, вы сможете вернуть IQueryable<T>
напрямую, а компилятор C # может использовать вывод типа, чтобы определить, что T
было во время компиляции. Это эффективно, как большинство операторов Linq построены, за исключением того, что они реализованы как методы расширения.
Например, рассмотрим метод, который удаляет любые из списка, которые являются значениями по умолчанию для этого типа:
public static IQueryable<T> FilterDefaults<T>(IQueryable<T> theSet)
{
IQueryable<T> query =
from t in theSet
where t != default(T)
select t;
return query;
}
Теперь, когда вы вызываете это в C #, вы можете пропустить <T>
, так как вывод типа может вычислить T
во время компиляции, чтобы все еще иметь строгий тип:
string[] myStrs = { "ABC", null, "", "123", null, "XYZ" };
var theFilteredStrs = FilterDefaults(myStrs);
// should represent the sequence: "ABC", "", "123", "XYZ"
// note null is missing because default(string) is null
int[] myNums = { -1, 0, 3, 0, 42 };
var theFilteredNums = FilterDefaults(myNums);
// should represent the sequence: -1, 3, 42
// note 0 is missing because default(int) is 0
Это тривиальный пример, который использует только базовые типы, но идея работает одинаково для любого использования LINQ (включая LINQ-to-SQL), которое является мощью LINQ. Не имеет значения, собираетесь ли вы в конечном итоге использовать LINQ-to-SQL или это просто LINQ-to-Objects.