IEnumerable <t>和IEnumerable的访问修饰符

时间:2019-03-06 05:15:40

标签: c#

我是C#的初学者,只是有关IEnumerable和IEnumerable的问题。我看到了一些这样的代码:

public class ShoppingCart : IEnumerable<Product>
{
   public IEnumerator<Product> GetEnumerator()
   {
      return Products.GetEnumerator(); 
   }
   IEnumerator IEnumerable.GetEnumerator() //why 'public' is not needed?
   {
      return GetEnumerator();
   }
}

我知道第一种方法是实现IEnumerator<Product>,第二种方法是实现IEnumerator,因为IEnumerator继承自IEnumerator<Product>,但是我不明白为什么不第二种方法需要'public'访问修饰符吗?第一种方法确实具有“公共”功能。 并且由于两个接口具有相同的方法签名,因此我们可以看到第二个方法使用interfacename.methodname作为显式接口实现,但是为什么第一个方法不需要此方法?不应该是:

public IEnumerator<Product>.GetEnumerator()
{
   ...
}

1 个答案:

答案 0 :(得分:2)

这归结为接口成员的隐式和显式实现之间的区别。

  • 除非将对象强制转换为实现的接口,否则显式实现的成员不会出现在对象上。如果希望某人能够调用new ShoppingCart().GetEnumerator(),则必须具有一个不是明确实现的GetEnumerator方法。假设它遵守已实现接口之一的约定,它将在该接口上隐式实现该方法。在这种情况下,必须指定一个访问修饰符,因为声明成员的主要目的是使其可以从此特定类中使用。修饰符必须至少与其实现的接口一样宽松(并且可能更宽松)。
  • 显式实现接口成员时,您不需要(实际上,您不能)指定可见性(例如public),因为可见性已经由接口本身设置。由于必须将对象强制转换为该接口才能访问该成员,因此不认为该成员具有超出接口可见性的可见性。

代码中的第一个方法可能已经被显式实现,如下所示:

IEnumerator<Product> IEnumerable<Product>.GetEnumerator()
{
    return Products.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
    return ((IEnumerable<Product>)this).GetEnumerator();
}

但是创建该类的人选择隐式实现它,这样它就可以使用而不必首先将ShoppingList强制转换为IEnumerable<Product>。请注意,这使其他方法的实现更加容易,因为他们可以简单地调用this.GetEnumerator()而不必先强制转换this

但是由于第二种方法与第一种方法的唯一不同之处在于返回类型,因此不可能隐式实现这两种方法。在这些情况下,显式实现非通用IEnumerable接口是常见的做法。