什么是隐含的generics类型参数

所以,我遇到了Servy( https://stackoverflow.com/a/15098242/496680 )的答案,他的一些代码执行了此操作:

public static int BinarySearch(...) 

对于扩展方法,但他称之为:

 arr.BinarySearch(...) 

我四处询问,有人提到它是一个隐含的generics类型参数。 我用谷歌搜索了他们,但没有找到关于他们的信息。 我理解generics如何工作,但我无法理解如何/何时使用这些。

  1. 为什么servy在他的扩展方法中使用它们?
  2. 我可以搜索这些更正式的名称吗?

好吧,你遗漏了最重要的部分,使它全部工作。 类型参数可以通过传入的实际对象参数来推断。

例如:

 static class Extensions { internal static IEnumerable Test( this IEnumerable items, Func converter) { foreach (T item in items) { yield return converter(item); } } } 

此扩展方法适用于任何 IEnumerable类,并将根据您提供的转换器将枚举中的每个项目转换为另一个类型。 这是标准的generics。

现在,有很多方法可以调用此方法:

 IEnumerable values = Enumerable.Range(1, 10); Func converter = i => i.ToString("0.00"); // Variation 1, explicit calling IEnumerable results1 = Extensions.Test(values, converter); // Variation 2, explicit calling with type inference IEnumerable results2 = Extensions.Test(values, converter); // Variation 3, extension method calling, still providing explicit types IEnumerable results3 = values.Test(converter); // Variation 4, extension method with type inference IEnumerable results4 = values.Test(converter); 

所有四种变体都调用相同的方法并返回相同的结果。 类型推断通过查看传递的参数并根据提供的内容自动推断其类型来工作。 在上面的示例中,它能够确定类型Tint类型,因为我们将IEnumerable传入IEnumerable的参数中。 它还能够推断出类型U是类型string因为我们传入了一个Func,它匹配初始类型的Tint并返回一个字符串。 所以FuncFunc转换函数填充。

从上面的推论中,它是那时的标准通用方法。 类型推断和扩展方法只不过是方便/句法糖。 实际上,如果您对输出进行反编译,则可以看到扩展方法被静态调用替换,并且通常使用显式填充的类型参数进行定义。 (这取决于您的反编译器和设置选项)。

  1. 在这种情况下,他使用generics方法 ,因为它允许他的方法使用Collection包含的任何类型。 通用方法使其非常灵活,可用于任何类型。 他在调用方法时使用类型推理,因为它简化了调用站点的代码。

  2. 自动处理称为类型干扰,详细介绍了C#语言规范,第7.5.2节:类型干扰。 如果您想详细了解它,我建议您下载C#语言规范 。

我经常听到的术语是“类型推断”。