Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么我们要递归地实现接口?_.net_Collections - Fatal编程技术网

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

.net 为什么我们要递归地实现接口?,.net,collections,.net,Collections,我理解任何集合(这里我说的是常规非泛型集合)都应该在常规对象集合中实现ICollection、IEnumerable和IList,在字典中实现IDictionary [尽管如此,我问的问题并不是针对收藏品] IList源自ICollection和IEnumerable ICollection派生自IEnumerable 让集合(例如ArrayList)实现IList还不够吗 在对象浏览器中,它显示集合类(例如ArrayList)正在实现IList、ICollection和IEnumerator

我理解任何集合(这里我说的是常规非泛型集合)都应该在常规对象集合中实现ICollection、IEnumerable和IList,在字典中实现IDictionary

[尽管如此,我问的问题并不是针对收藏品]

IList源自ICollection和IEnumerable

ICollection派生自IEnumerable

让集合(例如ArrayList)实现IList还不够吗

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

我理解,即使我们指定了所有三个集合,.Net也只接受一次定义

但我的问题是

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

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


  • 为了通过接口访问对象,对象的类定义必须显式定义它实现接口

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

    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函数。您描述的声明可能是多余的,但它们不是递归的。