繁体   English   中英

在 LINQ 扩展方法中指定泛型类型的原因

[英]Reasons to specify generic types in LINQ extension methods

只是出于好奇:

许多 LINQ 扩展方法以通用和非通用变体的形式存在,例如AnyAny<>WhereWhere<>等。编写我的查询时,我通常使用非通用变体,它工作正常。

什么情况下必须使用泛型方法?

- - 编辑 - -

PS:我知道内部只调用泛型方法并且编译器在编译期间尝试解析泛型括号<>的内容。 我的问题是什么情况下必须明确提供类型而不依赖于编译器的直觉?

总是。 C# 编译器足够聪明,可以根据参数推断方法的类型。 当类型是匿名的,因此没有名称时,这一点很重要。

obj.SomeMethod(123); //these calls are the same
obj.SomeMethod<int>(123);

obj.SomeMethod(new { foo = 123 }); //what type would I write here?!

编辑:要清楚,您总是在调用泛型方法。 它只是看起来像一个非泛型方法,因为编译器和 Intellisense 很聪明。

编辑:对于您更新的问题,如果您想使用不是您传递的 object 类型的类型,您需要具体说明。 有两种这样的情况:

  1. 如果参数实现了一个接口,并且你想对该接口进行操作,而不是具体类型,那么你应该指定接口:

     obj.DoSomething<IEnumerable<Foo>>( new List<Foo>() );
  2. 如果参数可以隐式转换为另一种类型,并且您想使用第二种类型,那么您应该指定它:

     obj.DoSomethingElse<long> ( 123 ); //123 is actually an int, but convertible to long

另一方面,如果您需要强制转换来进行转换(或者您仍然插入一个),那么您不需要指定:

obj.DoYetAnotherThing( (Transformed)new MyThing() ); // calls DoYetAnotherThing<Transformed>

我今天遇到的一个例子:

ObjectSet<User> users = context.Users;
var usersThatMatch = criteria.Aggregate(users, (u, c) => u.Where(c));

上面的代码不起作用,因为 .Where 方法不返回ObjectSet<User> 您可以通过以下两种方式之一解决此问题。 我可以在用户上调用.AsQueryable() ,以确保它被强类型化为 IQueryable,或者我可以将特定类型 arguments 传递给 Aggregate 方法:

criteria.Aggregate<Func<User, bool>, IEnumerable<User>>(
    PersonSet, (u, c) => u.Where(c));

另外两个更常见的示例是CastOfType方法,它们无法推断出您想要什么类型,并且在许多情况下,首先在非泛型集合上调用。

通常,设计 LINQ 方法的人会竭尽全力避免在这些泛型方法中使用显式类型,而且大多数情况下您不需要。 我会说最好知道这是一种选择,但除非您认为有必要,否则请避免这样做。

暂无
暂无

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

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