接口继承的声明问题 [C#, BCL]

接口继承的声明问题

 

Written by Allen Lee

 

某天,小新问我这样一个问题:

类System.Collections.CollectionBase是从IList、ICollection继承而来,IList是从ICollection和IEnumerable继承而来,那CollectionBase为什么还要从ICollection继承呢?

我们先来看看这些类和接口在MSDN文档中的声明:

public interface IEnumerable

public interface ICollection : IEnumerable

public interface IList : ICollection, IEnumerable

public abstract class CollectionBase : IList, ICollection, IEnumerable

根据接口继承的规则,我们知道CollectionBase只需要声明实现IList,就必须同时实现ICollection,也就必须实现IEnumerable,那么,我们为什么还要明确地把所有的这些接口都写下来呢?

换句话说,下面两种声明没有实质的区别:

// Code #1

public interface IEnumerable

public interface ICollection : IEnumerable

public interface IList : ICollection, IEnumerable

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

// Code #2

public interface IEnumerable

public interface ICollection : IEnumerable

public interface IList : ICollection

public class ArrayList : IList, ICloneable

那为何MSDN要使用上面那种呢?我和小新讨论后,一致认为这样做仅仅为了提高代码的可读性。为了验证我们的想法,我分别发邮件给Eric Gunnerson(Eric是C# Compiler Team的成员)和Kit George(Kit是BCL Team的成员)询问这个问题,他们的回信如下:

Allen,

I think that readability would be the primary reason people would do this.

Eric

Allen, what you’re seeing is simply a doc thing. ArrayList actually only implements IList directly, but we decided in V1.0 of the docs, to highlight the interface hierarchy so you didn’t have to wonder ‘what does IList implement’, you get to see it there on the type.

There is no benefit to ACTUALLY doing this. Try this code, and you’ll see it compiles:

using System;
using System.IO;

public class Test : IBob2
{
    
void IBob.M() {}
}


interface IBob
{
    
void M();
}


interface IBob2 : IBob {}

Regards,

Kit

今天,我查看微软的Rotor源代码,发现ArrayList的声明的确是Code #1的做法,不过Mono(ver. 1.1.2 Development Version)就采用了Code #2的做法。

所以,以后如果你再碰到到这样的情况,你可以轻松的笑一声:“这样做是为了提高代码的可读性的!”

 

posted @ 2004-11-16 14:21 Allen Lee 阅读(2740) 评论(8)  编辑 收藏 所属分类: C#

  回复  引用  查看    
#1楼 2004-11-16 14:39 | montaque      
呵呵,我也曾问过Eric。
  回复  引用  查看    
#2楼 2004-11-16 14:49 | fengzhimei      
great.
  回复  引用    
#3楼 2004-11-16 16:53 | Ninputer [未注册用户]
你们刨根问底的精神值得赞扬。再想一个问题怎么样,如果有
class A : Interface1

那么
Class B : A, Inteface1

Class B : A

会出现什么不同的情况呢。编译器在IL级别是用什么手段实现这个功能的呢?
  回复  引用  查看    
#4楼 2004-11-16 18:22 | sumtec      
不错,有价值。
  回复  引用  查看    
#5楼 2004-11-16 19:23 | 寒枫天伤      
@Ninputer

class A : Interface1

那么
Class B : A, Inteface1

Class B : A

如果是Class B:A的话,则B继承于A,成员也是如此,没什么说的.

但如果是Class B : A, Inteface1的话,则B中需重新实现接口Interface1的成员,这是接口的重新映射.
  回复  引用  查看    
#6楼 [楼主]2004-11-16 21:37 | Allen Lee      
To Ninputer:
 
对于你所提出的问题,我已经在《基类与接口混合继承的声明问题 [C#, Design]》一文作了解释,请你指教一下。

  回复  引用    
#7楼 2006-06-01 17:43 | sadfasdf [未注册用户]
可不可以在基类中实现接口的一部分,在在子类中实现剩下的部分(vb.net)
interface test
sub a()
sub b()
sub c()
end interface
mustherits class mybaseclass
implements test
sub a () implements test.a
sub b () implements test.b
end class
class myclass
inherits mybaseclass
implements test
sub c () implements test.c
end class
我现在在vb.net中就碰到这样的问题,但在两个类中,由于都没有完全实现借口,所以编译都通不过,如何实现类型功能?,谢谢.anqincmt@tom.com

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-10-23 07:38 编辑过


相关链接: