许多LINQ方法采用
的形式MethodName<Type>();
看来,在调用这些方法时,Type
是可选的。例如,这两个陈述似乎产生相同的结果:
var a = someStringList.First<string>();
var b = someStringList.First();
为什么我要输出该声明的<string>
部分?是否存在实用性的情况?
答案 0 :(得分:6)
首先,请注意,这适用于任何泛型方法,而不仅仅是LINQ方法。
通常,您不需要在泛型方法上指定类型,因为通常可以从使用中推断出类型。例如:
T SomeFunc<T>(T arg) {....}
var x = SomeFunc("Hello World");
由于我们使用了一个字符串作为参数,编译器决定T
是一个字符串,因此我们得出结论该方法将返回一个字符串。
其他时候,它不能推断它:
T SomeOtherFunc<T>(string arg) {....}
var x = SomeOtherFunc("Hello World"); // error : cannot infer type
在这种情况下,您必须指定类型:
var x = SomeOtherFunc<int>("Hello World"); // x will be an int.
如果您真的想要,为了更加清晰,您可以指定类型,即使它可以推断出来,但它必须是正确的:
T SomeFunc<T>(T arg) {....}
var x = SomeFunc<string>("Hello World"); // OK
var y = SomeFunc<int>("Hello World"); // Error
最后,请记住,对于扩展方法,例如示例中的First<>
,该对象实际上是第一个参数,因此可以在类型推断中使用。 First<>
将被定义为:
public static T First<T>(this IEnumerable<T> coll) ;
答案 1 :(得分:4)
因为在第二种类型中,编译器会根据someStringList
的类型自动推断出类型。由于它是IEnumerable<string>
编译器,因此将泛型参数类型解析为string
。
好的,所以听起来好像可以用来施展......为什么不使用.Cast?
因为Cast
方法采用非通用IEnumerable
作为第一个参数,所以无法推断出类型,这就是您需要提供它的原因。