如果我导入了System.Linq
,我可以在以下调用中使用此ToArray重载:
var x = "foo".ToArray();
并且CCD_ 2被分配具有作为来自字符串CCD_ 4的字符的三个元素的CCD_。然后,如果我在作用域中添加一个自定义扩展方法:
public static T[] ToArray<T>(this T toConvert) => new[] { toConvert };
编译器无声地改变主意,x
变成了一个string[]
,其中有一个元素,即字符串"foo"
。
为什么编译器没有抱怨歧义?我知道编译器会自动解决一些看似模棱两可的情况,但我找不到任何关于这种情况的文档或参考资料。基本上,将string
视为string
而不是char
的隐式数组似乎是首选行为。。。
您引用的第一个扩展方法:
public static TSource[] ToArray<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);
将IEnumerable<TSource>
转换为数组(泛型类型的接口(。
您制作的第二种扩展方法:
public static T[] ToArray<T>(this T toConvert) => new[] { toConvert };
将任何T对象转换为单个对象数组。由于这是一个没有接口的泛型类型,因此它比采用具有泛型类型的接口的扩展方法更可取。本质上,与泛型类型的接口相比,在其上应用扩展是潜在类型的一个更大的覆盖面。编译器更喜欢与扩展方法匹配的具体类型,而更喜欢匹配的接口。
C#语言规范,向下大约60%找到Method Overloading
:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/introduction
C#过载解决方案:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.3/improved-overload-candidates
VB版本,虽然主要适用于C#:https://learn.microsoft.com/en-us/dotnet/visual-basic/reference/language-specification/overload-resolution