【发布时间】:2018-01-09 22:46:59
【问题描述】:
作为示例,使用 String 类中的 Join() 方法。当你调用它时 一个字节数组,例如
byte[] bytes = {3,4,5};
string str = string.Join(",", bytes);
C# 编译器将 Join 映射到此签名
public static String Join<T>(String separator, IEnumerable<T> values);
但是,byte[] 隐式派生自类 Array,该类并非派生自泛型 IEnumerable,而是派生自非泛型 IEnumerable,即
public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable {...}
如果我对自己的类似于这种情况的接口和类做同样的事情,我会得到 预期的编译器错误,因为根据规则您不能强制转换类 从接口 IA(非通用 IEnumerable)派生到接口 IB(通用 IEnumerable) 源自 IA。这意味着 C# 编译器只是硬编码特定名称 IEnumerable。 这是在哪里解释的?
【问题讨论】:
-
IEnumerable 没有特殊处理,但是 Array 协方差有特殊处理。 docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
-
byte[]实际上实现了IEnumerable<byte>(更具体地说,it implementsIList<byte>)。神奇之处不在IEnumerable,而在于处理数组的方式。查看Array的元数据不会告诉你一切。 -
@ScottChamberlain 这里没有数组协方差。
-
@Servy 这就是为什么这是评论而不是答案。对于 OP 来说,这更像是一个仅供参考的方面。
-
The documentation 清楚地解释了某些接口的通用形式的实现,包括
IEnumerable<T>是由运行时提供的。而且,您的问题已经在之前的 Stack Overflow 帖子中得到了很好的解决。
标签: c#