翻看 AutoMapper的源码,我发现了一件有趣的事情:
类Mapper:
public class Mapper : IRuntimeMapper, IMapper
{
//...
接口IRuntimeMapper:
public interface IRuntimeMapper : IMapper
{
//...
问题
如果它已经继承自它,为什么要Mapper实现它?这个“错误”是在库的扩展过程中发生的,还是这是正常的做法?IMapperIRuntimeMapper
在 github 行上的 automapper 的源代码中
从广泛的海鸥来看,它不存在,也从未存在过。
反编译器可以出于一个相当奇怪的原因显示整个接口继承链 - C# 中的类和接口继承的工作方式不同。
在类层次结构的情况下,每个孩子都有一个明确的父母:
在接口的情况下,触发层次结构崩溃机制:
编译器搜索所有基本接口,构建它们的完整列表,并将它们附加为已实现的接口。于是他转
在
继承接口列表就是以这种形式存储在元数据中的,反编译器根本无法判断原始代码中是否提到了两个接口,或者编译器是否添加了它们。
如果您查看了反编译的源代码,那很好。比较: BlockingCollection 来源和MSDN 描述。JetBrains 反编译器会显示帮助中的状态,尽管类型明显不同。
我有两个主要想法为什么会这样。要么所有实现接口的信息都存储在一个地方,并且不会每次都尝试构建继承树(并且此信息会反编译工具),要么只是为了方便,以免每次都尝试记住,而是这些接口中的每一个都实现了任何其他接口。
虽然,正如@PashaPash 注意到的那样
从来没有上过 GitHub。这种情况绝非罕见。例如,一个标准类
List<T>实现以下接口:虽然文档包含更大的列表:
什么是重要的:
IList<T>继承ICollection<T>和IEnumerable<T>ICollection<T>继承IEnumerable<T>和IEnumerableIEnumerable<T>继承IEnumerable看来这一切究竟是为了什么,目的是什么?Eric Lippert对类似问题的回答解释了何时出现类似代码:
另一个开发者的代码,作者的目标是(在作者看来)使代码更容易理解和更自文档化
当涉及到文档时,目标是提供尽可能多的信息,避免您自己弄清楚继承链的麻烦。
当涉及到反编译工具时,目标是显示更多信息,而不是向您隐藏其中必要的部分。此外,由于此类工具仅依赖于元数据并且没有必要指定完整的接口列表,因此该工具可能不知道源代码是否包含整个列表。因此,最好在过度信息方面犯错。