如何解决为什么编译器选择字符串上的扩展方法而不是隐式字符数组?
如果我导入了 System.Linq
,我可以在以下调用中使用 this ToArray overload:
var x = "foo".ToArray();
和 x
被分配了一个 char[]
,其中三个元素是字符串 "foo"
中的字符。然后,如果我在范围内添加自定义扩展方法:
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://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/introduction
VB 版本,虽然主要适用于 C#: https://docs.microsoft.com/en-us/dotnet/visual-basic/reference/language-specification/overload-resolution
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。