Normally when you implement an interface, you must specify public
for the methods and properties. In this case, not only do those methods and properties contribute towards implementing the interface, they are also just like any other regular method or property. Being able to add public
to them makes sense. However, the IEnumerator.GetEnumerator
you've declared here is a bit special.
This is an explicit interface implementation of IEnumerable.GetEnumerator
. Just in case you didn't know, this is the non-generic (by which I mean, returns a non-generic IEnumerator
) version of IEnumerable<T>.GetEnumerator
, declared in IEnumerable
(not to be confused with IEnumerable<T>
!). Since IEnumerable<T>
inherits from IEnumerable
, you are required to implement both when implementing IEnumerable<T>
.
If you didn't use an explicit interface implementation here, you would have two methods with the same name, both accepting no parameters, with only the return value different:
public IEnumerator<int> GetEnumerator()
{
...
}
public IEnumerator GetEnumerator() // CS0111
{
...
}
This is not allowed. This is where explicit interface implementation comes in. If you declare the non-generic GetEnumerator
by prefixing the name of the interface where it comes from:
IEnumerator IEnumerable.GetEnumerator()
{
...
}
Then this method is only accessible on an expression with a type of IEnumerable
. For example, let's say your collection is called MyCollection
.
MyCollection myCollection = ...;
// this accesses the *generic* GetEnumerator, the non-generic one is not accessible
myCollection.GetEnumerator()
// the non generic one is only accessible if you cast to IEnumerable
((IEnumerable)myCollection).GetEnumerator()
Even if in the same class, you can't access the non-generic GetEnumerator
without casting to IEnumerable
first. Do you see how this is somewhat different from what private
usually means? None of the access modifiers can really express the accessibility of explicit interface implementations, to be honest.