• 全部
...

在一个继承体系上定义多个相同的接口是基于什么样的理由?

Dic4000 2018-04-27 10:41:47
.NET官方文档中非泛型IList接口的定义是:

  1. public interface IList : ICollection, IEnumerable

而ICollection接口的定义本身也会继承自IEnumerable,如下图:

  1. public interface ICollection : IEnumerable

既然IList 继承自ICollection ,而ICollection 又继承自IEnumerable,

那么为何IList的定义中还要显示声明继承自IEnumerable呢?如果IList的定义去掉显示的IEnumerable继承, 像下面这样会有什么潜在的问题?

  1. public interface IList : ICollection

类似这样重复继承相同接口的现象在.NET Framework BCL中有很多,为什么要这样设计呢?是基于什么样的思想呢?
...全文
给本帖投票
420 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
圣殿骑士18 2018-04-27
  • 打赏
  • 举报
回复
我认为是为了编程的方便性。 我们假设IEnumerable还继承自IAbc,那么IList的定义最好是写为: public interface IList : ICollection, IEnumerable,IAbc 而如果我们不这么写,而是遵循尽量简写的方式,那就是: public interface IList : ICollection 那么问题来了,但编程者想做这么一个事情,他在某个编程场景下,想将IList转换为更基类的接口,他怎么知道能转的那个接口名是IAbc? 他无法知道,除非他已经把它记在脑子里,或者他必须先进入IList的接口定义,再进入ICollection的接口定义,再进入IEnumerable的接口定义,终于能看到了: public interface IEnumerable: IAbc 然后,他将Ilist实例转换成IAbc。 是不是很麻烦? 而如果写成: public interface IList : ICollection, IEnumerable,IAbc 他进入IList接口定义,就很清晰的知道,他可以转换的接口一共有哪些。这就是编程者利用类无法多继承,而接口可以多继承的好处,给编程上带来一些便利。
  • 打赏
  • 举报
回复
如果你看的“官方文档”中的所记录的代码是最近这些年写的,那么它就很可能写成
public interface IList : ICollection
这样的了,因为微软写 .net 新的类库的时候就会使用 c# 最新版本来写代码。
  • 打赏
  • 举报
回复
早期的 c# 版本并不支持接口继承。现在支持了,这是语法糖的功劳。 比如说代码
    class Program
    {
        static void Main(string[] args)
        {
            IA x = new XX();
        }
    }

    interface IA
    {
        string X { get; }
    }

    interface IB : IA
    {
        string Y { set; }
    }

    interface IAB: IB
    {

    }

    public class XX : IAB
    {
        public string Y { set => throw new NotImplementedException(); }

        public string X => throw new NotImplementedException();
    }
它编译到 MSIL 之后,编译器产生的代码是
.class public auto ansi beforefieldinit ConsoleApp1.XX
	extends [mscorlib]System.Object
	implements ConsoleApp1.IAB,
	           ConsoleApp1.IB,
	           ConsoleApp1.IA
{
	// Methods
	.method public final hidebysig specialname newslot virtual 
		instance void set_Y (
			string 'value'
		) cil managed 
	{
		// Method begins at RVA 0x206d
		// Code size 6 (0x6)
		.maxstack 8

		IL_0000: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
		IL_0005: throw
	} // end of method XX::set_Y
        ..............................
可以看出,其实 .net framework 根本不支持接口继承,所以编译器自动地在生成 XX 类型定义代码时及加入了更多的接口声明。 早期的 c# 并不支持接口继承,并不会产生这类代码。这是最近10年的c#编译器才有的特性。而最早的 c# 源代码,或者你只是通过“反编译工具”看到的源代码,就会看到
public class XX : IAB, IB, IA
{
    .............
这类代码形式。

111,090

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部