Today, another question from StackOverflow, and again, presented as a dialogue as is my wont.
The MSDN documentation for List<T> says that the class is declared as
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,
IList, ICollection, IEnumerable
Does List<T> really implement all those interfaces?
Yes.
Why so many interfaces?
Because when an interface like IList<T> inherits from an interface like IEnumerable<T> then implementers of the more derived interface are required to also implement the less derived interface. That's what interface inheritance means; if you fulfill the contract of the more derived type then you are required to also fulfill the contract of the less derived type.
So a class or struct is required to implement all the methods of all the interfaces in the transitive closure of its base interfaces?
Exactly.
Is a class (or struct) that implements a more-derived interface also required to state in its base type list that it is implementing all of those less-derived interfaces?
No.
Is the class required to not state it?
No.
So it's optional whether the less-derived implemented interfaces are stated in the base type list?
Yes.
Always?
Almost always:
interface I1 {}
interface I2 : I1 {}
interface I3 : I2 {}
It is optional whether I3 states that it inherits from I1.
class B : I3 {}
Implementers of I3 are required to implement I2 and I1, but they are not required to state explicitly that they are doing so. It's optional.
class D : B {}
Derived classes are not required to re-state that they implement an interface from their base class, but are permitted to do so. (This case is special; see below for more details.)
class C<T> where T : I3
{
public virtual void M<U>() where U : I3 {}
}
Type arguments corresponding to T and U are required to implement I2 and I1, but it is optional for the constraints on T or U to state that.
It is always optional to re-state any base interface in a partial class:
partial class E : I3 {}
partial class E {}
The second half of E is permitted to state that it implements I3 or I2 or I1, but not required to do so.
OK, I get it; it's optional. Why would anyone unnecessarily state a base interface?
Perhaps because they believe that doing so makes the code easier to understand and more self-documenting.
Or, perhaps the developer wrote the code as
interface I1 {}
interface I2 {}
interface I3 : I1, I2 {}
and the realized, oh, wait a minute, I2 should inherit from I1. Why should making that edit then require the developer to go back and change the declaration of I3 to not contain explicit mention of I1? I see no reason to force developers to remove redundant information.
Read more: Fabulous Adventures In Coding
0 comments:
Post a Comment