为什么我们递归地实现接口?

时间:2010-08-16 19:28:37

标签: .net collections

我理解任何Collection(这里我说的是常规的非泛型)应该已经实现了ICollection,IEnumerable和IList包含常规对象集合或IDictionary(如果是字典)。

[尽管如此,我问的问题并非特定于收藏]

IList派生自ICollection和IEnumerable

ICollection派生自IEnumerable

是否仅仅使集合(例如ArrayList)实现IList?

在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList,ICollection和IEnumerator。

据我所知,即使我们指定了所有三个集合,.Net也只会接受一次定义。

但我的问题是,

  1. 是否有任何最佳实践或建议指导我们为集合类指定所有三个接口(或者与此类似的任何类)?

  2. 或者只是对象浏览器的特性将它显示为3个独立的实现? [刚查过,发现它不是Object浏览器的属性。对象浏览器只显示类定义中指定的接口]

5 个答案:

答案 0 :(得分:5)

相信只是对象浏览器以这种方式显示它。我刚试过这个:

using System.Collections;
using System.Collections.Generic;

public class Foo : IEnumerable<int>, IEnumerable
{
    public IEnumerator<int> GetEnumerator() { return null; }
    IEnumerator IEnumerable.GetEnumerator() { return null; }

}

public class Bar : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator() { return null; }
    IEnumerator IEnumerable.GetEnumerator() { return null; }
}

将其加载到对象浏览器中,两个类都显示了两个接口。

请注意,如果您继承自另一个实现,有时可以重新声明接口 - 它允许您重新实现接口(如果之前已实现)明确地或以非虚拟方式。我不相信这种情况,但值得一提。

一般情况下,你绝对不必指定所有接口,我通常不会这样做。

答案 1 :(得分:2)

  

是否仅仅使集合(例如ArrayList)实现IList?

这就够了。宣布课程:

public MyCollectionClass : IList {
}

这意味着你的MyCollectionClass实现了IList,ICollection和IEnumerable。

  

在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList,ICollection和IEnumerator。

这是对象浏览器的细节,或者基类通过指定所有接口简单地实现了集合类。然而,确实没有任何理由这样做。

答案 2 :(得分:2)

现在,我认为你问的是,给定

interface IA {};
interface IB : IA {};
interface IC : IB {};

有什么区别:

class MyClass : IC {};

class MyClass : IA, IB, IC {};

答案是,绝对没有。第二个版本使其设计对其他程序员来说更清晰,但要么生成相同的代码。

答案 3 :(得分:1)

为了通过接口访问对象,对象的类定义必须明确定义它实现接口...

例如,我可以拥有以下内容:

interface IAnimal {
  public void Yelp();
}

以及以下课程:

class Dog {
  public void Yelp() { 
     // do yelping
  }
}

现在,狗确实在喊叫;但是,因为它没有声明它实现了IAnimal,我不能执行以下操作:

IAnimal poodle = new Dog();
poodle.Yelp();

为了解决这个问题,必须将Dog的定义更改为:

class Dog : IAnimal {
  public void Yelp() { 
     // do yelping
  }
}

答案 4 :(得分:1)

我认为这要么是开发人员要清楚,要么是为了帮助强制执行界面结构。我的意思是,假设您有一个数据结构类的接口,并且您实现了IDataObject。然后,IDataObject实现ISecurable和ILoggable。您创建的常规类可能只是实现IDataObject,但是如果IDataObject的创建者稍后更改实现并丢弃ILoggable会怎么样?这可能会更改代码的功能。因此,为了防止这种情况,当您创建继承自IDataObject的类时,您可以明确地说您还要实现ISecurable和ILoggable,只是为了安全。

我不确定为什么他们会与IList合作,但这两个原因是我最好的猜测原因。