.net 为什么我们要递归地实现接口?
我理解任何集合(这里我说的是常规非泛型集合)都应该在常规对象集合中实现ICollection、IEnumerable和IList,在字典中实现IDictionary [尽管如此,我问的问题并不是针对收藏品] IList源自ICollection和IEnumerable ICollection派生自IEnumerable 让集合(例如ArrayList)实现IList还不够吗 在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList、ICollection和IEnumerator 我理解,即使我们指定了所有三个集合,.Net也只接受一次定义 但我的问题是.net 为什么我们要递归地实现接口?,.net,collections,.net,Collections,我理解任何集合(这里我说的是常规非泛型集合)都应该在常规对象集合中实现ICollection、IEnumerable和IList,在字典中实现IDictionary [尽管如此,我问的问题并不是针对收藏品] IList源自ICollection和IEnumerable ICollection派生自IEnumerable 让集合(例如ArrayList)实现IList还不够吗 在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList、ICollection和IEnumerator
为了通过接口访问对象,对象的类定义必须显式定义它实现接口 例如,我可以有以下内容:
interface IAnimal {
public void Yelp();
}
IAnimal poodle = new Dog();
poodle.Yelp();
以及以下类别:
class Dog {
public void Yelp() {
// do yelping
}
}
现在,这只狗确实在叫;但是,由于它没有声明它实现IAnimal,因此我不能执行以下操作:
interface IAnimal {
public void Yelp();
}
IAnimal poodle = new Dog();
poodle.Yelp();
为了解决此问题,必须将Dog的定义更改为:
class Dog : IAnimal {
public void Yelp() {
// do yelping
}
}
让集合(例如ArrayList)实现IList还不够吗
够了。声明类:
public MyCollectionClass : IList {
}
这意味着您的MyCollectionClass实现了IList、ICollection和IEnumerable
在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList、ICollection和IEnumerator
这是对象浏览器的详细信息,或者基类只是通过指定所有接口来实现集合类。然而,这样做确实没有任何驱动理由。我相信,正是对象浏览器以这种方式显示它。我刚刚试过这个:
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; }
}
使用系统集合;
使用System.Collections.Generic;
公共类Foo:IEnumerable,IEnumerable
{
公共IEnumerator GetEnumerator(){return null;}
IEnumerator IEnumerable.GetEnumerator(){return null;}
}
公共类栏:IEnumerable
{
公共IEnumerator GetEnumerator(){return null;}
IEnumerator IEnumerable.GetEnumerator(){return null;}
}
将其加载到对象浏览器中会显示两个类上的两个接口
请注意,如果您是从另一个实现继承的,有时可能需要重新声明一个接口—它允许您重新实现以前显式实现或以非虚拟方式实现的接口。我不相信这里的情况是这样,但值得一提
但一般来说,您肯定不必指定所有接口,我通常也不会这样做。现在,我想您是在问,如果
interface IA {};
interface IB : IA {};
interface IC : IB {};
这两者之间的区别是什么:
class MyClass : IC {};
及
答案是,绝对没有。第二个版本使它的设计对其他程序员来说更清晰一些,但两者都会生成相同的代码。我认为这只是为了让开发人员更清楚,或者帮助加强接口结构。我的意思是,假设您有一个用于数据结构类的接口,并且您实现了IDataObject。IDataObject然后实现ISecurable和ILograble。您创建的常规类可以只实现IDataObject,但是如果IDataObject的创建者稍后更改了实现并删除了ILOGABLE呢?这可能会更改代码的功能。因此,为了防止这种情况,当您创建从IDataObject继承的类时,为了安全起见,您可以明确地说您还希望实现ISecurable和ILogable
我不知道他们为什么用IList这样做,但这两个原因是我最好的猜测。这对我在VS2010中不起作用。此外,对于我的自定义类,对象浏览器忽略了隐含的接口。@ladenedge:这也是我在VS2010中遇到的(如果相关的话,是VS2010 Pro)。它向我展示了“基本类型”中的接口。你在那里看到了什么?嗨,谢谢你的回复。但它不是对象浏览器的属性。我以前发现过。如果我们仅从IList派生,则对象浏览器仅显示IList。如果我们同时从IList和IEnumerable派生,则对象浏览器会同时显示这两个对象。@Saravandandss:同样,这不是我的经验(使用VS2010对象浏览器)。我刚刚在第三个类中实现了IList,它仍然显示对象浏览器中的所有接口。也许这取决于编译器的版本?@Jon Skeet:它们都在树视图中,但它们仍然以不同的方式显示-(VS2010 Pro对我来说也是如此,fwiw)。此外,右下角类似MSDN的类定义视图在任何程度上都不包括隐含接口。类或基类的定义必须指定它实现接口。如果Dog实现了IAnimal,而Poodle继承了Dog,那么Poodle可以被强制转换为IAnimal并调用Yelp函数。您描述的声明可能是多余的,但它们不是递归的。