【问题标题】:Why does List<T> implement IList<T>, ICollection<T> and IEnumerable<T>?为什么 List<T> 实现 IList<T>、ICollection<T> 和 IEnumerable<T>?
【发布时间】:2019-01-17 11:07:27
【问题描述】:

如果您转到List&lt;T&gt; 的定义,您会看到以下内容:

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>

IList&lt;T&gt; 已经继承自 ICollection&lt;T&gt;IEnumerable&lt;T&gt;

如果List&lt;T&gt; 只实现IList&lt;T&gt; 还不够吗?

【问题讨论】:

    标签: c#


    【解决方案1】:

    是的,在这种情况下没有区别。在某些情况下,它可以有所作为,如果您使用的基类已经实现了一个接口,但您希望自己显式地重新实现它 - 但在这种情况下,没有基类(除了隐式 object) 并且它的行为方式完全相同。

    与我的回忆相反,我认为无论代码是否显式声明所有接口,元数据中的类表示方式都没有区别。这是一个例子:

    interface IFoo {}
    interface IBar : IFoo {}
    
    class FooBar1 : IBar {}
    class FooBar2 : IBar, IFoo {}
    

    ildasm 和 Reflector 都为 FooBar1FooBar2 显示相同的信息...它显示它们都实现了 IBarIFoo

    换句话说,我们无法判断List&lt;T&gt; 的原始源代码是否实际上指定了所有接口。也许有,也许没有——但不管怎样都无所谓。

    编辑:为了完整起见,我还检查了您使用另一个接口扩展两个接口的情况。在这种情况下,我也找不到元数据的差异。我确定我记得某些情况很明显,但我现在找不到了。

    【讨论】:

    • 所以既然没有基类。这没什么区别。那为什么开发者“再次”继承了这两个接口?
    • 知道了。非常感谢。很快。
    • @Jon Skeet:我爱你。我想实现你的 IBrain。我可以继承“你的”基类吗?
    • @WhileTrueSleep:恐怕我听不懂你的评论。
    【解决方案2】:

    是的。 IList&lt;T&gt; 本身实现了另外两个。

    对象浏览器向您显示所有类实现的接口,无论是直接(IList&lt;T&gt;)还是间接(ICollection&lt;T&gt;IEnumerable&lt;T&gt;通过@987654325 @)。

    【讨论】:

    • 你的意思是这只是对象浏览器为了让我们更容易做的一个小把戏?
    • 好吧,如果你想这样说的话。我真的认为这是因为浏览器的代码只是列出了所有实现的接口,而不关心过滤掉别人扩展的那些。
    【解决方案3】:

    这不是它在幕后实际编码的方式。这正是 Reflector 等工具在将 IL 转换回 C# 时向您展示的内容。

    【讨论】:

    • @Incognito:codeviewer 从元数据生成它,就像反射器一样。
    【解决方案4】:

    如果你查看了源代码:

    https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

    可以观察到签名是:

    public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
    

    这只能意味着元数据浏览器对我们的继承层次结构进行了反规范化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 2018-01-05
      • 2011-06-14
      • 1970-01-01
      相关资源
      最近更新 更多