tags:

views:

323

answers:

3

I'm creating a specialised proxy class that implements IList<T> and wraps an internal List<T> instance.

List<T> itself implements IList<T>, which declares a member bool IsReadOnly, but when I try to access that member from my own class, I can't because in List<T>, IsReadOnly is private.

So my question is; if an implementation of an interface requires all implemented members to be public, why does List<T> get to implement IsReadOnly as private and thus deny me access to it?

+6  A: 

It implements the interface member explicitly.

http://msdn.microsoft.com/en-us/library/aa288461(VS.71).aspx

Note that this does not make the interface member private. It's still available publicly, but only if you look at the object through the interface (with casting).

Mehrdad Afshari
+5  A: 

The reason it's able to do this is that it uses explicit interface implementation.

bool IList<T>.IsReadOnly { get { ... } }

This member is still accessible, but it can only be accessed via the IList<T> type.

List<T> list = ...;
bool isReadOnly = ((IList<T>)list).IsReadOnly;

When implementing IList<T>, the type has not promised to provide an IsReadOnly value itself. Instead it's promised to provide an IsReadOnly property when viewed as an IList<T>. Whether or not it provides it on the actual class is purerly a choice of the type author.

JaredPar
@JaredPar: You cannot declare an access modifier on EII.
Mehrdad Afshari
@Mehrdad, yeah I get that backwards a lot. VB and C# have differing behavior here.
JaredPar
+2  A: 

For the case if List<T>, IsReadOnly doesn't really make sense: it's always false. List therefore implements the ICollection<T> (and the IList) interface explicitly, thus making the interface “private” for normal use. If you need to access it anyway, you can through an explicit cast to the interface:

bool result = ((ICollection<string>)yourStringList).IsReadOnly;
// Or equivalently using `IList`.
Konrad Rudolph