C# 泛型类型推断
我对泛型很满意,但作为一个喜欢理解每一个细节的人,我有这个问题。在我对C# 泛型类型推断,c#,.net,linq,generics,C#,.net,Linq,Generics,我对泛型很满意,但作为一个喜欢理解每一个细节的人,我有这个问题。在我对WhereLINQ扩展方法的实现中 public static class Extensions { public static IEnumerable<T> Where<T>( this IEnumerable<T> source, Func<T, bool> predicate)
Where
LINQ扩展方法的实现中
public static class Extensions
{
public static IEnumerable<T> Where<T>(
this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (T element in source)
if (predicate(element))
yield return element;
}
}
谢谢您的帮助。参数列表前面的
有点像“变量声明”—就像您不能只说:
x = 10;
您需要首先声明该变量:
int x = 10;
这里是类型的变量声明
现在使用,这是另一回事了-编译器将尽最大努力根据使用情况和现有签名推断出这些Type
变量中每个变量的“值”,但这些签名仍然必须声明
公共静态IEnumerable其中(此IEnumerable源,Func谓词)
有了这样一个签名,T
将是一个未声明的标识符。如果未在任何地方定义T
,则不能仅使用IEnumerable
。因此,您需要在方法(或者在类)级别上使用一个通用参数T
,才能使IEnumerable
有意义。没有任何理由认为IEnumerable
中的T
和其中的必须是相同的东西;通过将它们都指定为T
IEnumerable
是该方法返回的内容<代码>其中
用于定义用作参数的泛型类型。如果您没有将它们都指定为T
也就是说:返回类型(IEnumerable
)不一定与参数类型相关(其中中的T
)
但是在这种情况下会发生什么呢
Foo.Bar(null); //error
无法推断类型参数,如果是在编译时,则会出现编译错误
Foo.Bar<string>(null); //works
Foo.Bar(空)//作品
您将方法的定义和用法混为一谈
在定义(和声明)函数时,您需要那里的type参数来向编译器显示该方法是泛型的。声明类型参数T
后,可以使用它显示输入和输出参数的类型(在本例中为IEnumerable
)
当使用该方法时,您不需要指定它-它可以很好地从第一个输入参数推断出来。如果不确定,请尝试以下操作:
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var odds = numbers.Where(x => x % 2 != 0);
// test for example odds is IEnumerable<int> if you want confirmation =)
var number=新列表{1,2,3,4,5};
var赔率=数字。其中(x=>x%2!=0);
//例如,如果希望确认,则测试赔率为IEnumerable=)
我认为它可以,但在它不能的情况下,它是存在的。在大多数情况下,您可以使用Where
而不提供T
。@JonathanWood:他说的是声明签名,而不是调用。无论如何,为了能够提供T
,它必须在声明中。我错过了什么?@Mark例如,如果您声明公共类T{}
编译器会做什么?您的方法是否突然变得非泛型,因为在另一个文件中有人声明了名为T
的类型?@标记否,您的新版本没有声明泛型方法。它是一种普通方法,其形式参数和返回类型为封闭泛型类型(例如,IEnumerable
,在这种情况下,T
是实际类型),但方法本身不是泛型的。泛型方法具有一个或多个类型参数,在调用该方法时必须为其指定(或推断)类型参数。将其声明为,其中
表示这是一个具有单个类型参数的通用方法,该类型将由占位符T
表示。
Foo.Bar(null); //error
Foo.Bar<string>(null); //works
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var odds = numbers.Where(x => x % 2 != 0);
// test for example odds is IEnumerable<int> if you want confirmation =)