Does ReadOnlyCollection<T> implement IList<T> ?


L

Lucian Wischik

Does ReadOnlyCollection<T> really implement IList<T>, like it claims
to do? ...


When I right-click on ReadOnlyCollection and look at its definition,
it says this:

public class ReadOnlyCollection<T>
: IList<T>,ICollection<T>,IEnumerable<T> ...

However, the following code fails its assertion check:

List<string> xs = new List<string>();
ReadOnlyCollection<string> ro = new ReadOnlyCollection<string>(xs);
IList<string> il = ro as IList<string>;
Debug.Assert(il != null);

I don't understand how this is possible. If ReadOnlyCollection<T>
claims to implement IList<T>, then I should be able to cast to it,
shouldn't I?


In a similar vein, the following code fails to compile because, it
claims, ReadOnlyCollection<string> doesnt implement the Insert method.
How is this possible? Insert is part of IList<T>, which
ReadOnlyCollection<T> inherits from, so it should be there!

ro.Insert(0,"hello");



I'm asking these questions because I want to create my own
wrapper-class, similar to how ReadOnlyCollection is a wrapper around
an IList. I need to understand which interfaces I should declare
myself as providing. And so I need to understand why
ReadOnlyCollection declares that it supports the interfaces it does,
and how.

I wonder if ReadOnlyCollection really does implement those interfaces,
but somehow *hides* the Insert method &c.? How is this done in C#? The
documentation specifically says that methds from interfaces must be
public, so I don't know.
 
Ad

Advertisements

J

Jon Skeet [C# MVP]

Lucian Wischik said:
Does ReadOnlyCollection<T> really implement IList<T>, like it claims
to do? ...


When I right-click on ReadOnlyCollection and look at its definition,
it says this:

public class ReadOnlyCollection<T>
: IList<T>,ICollection<T>,IEnumerable<T> ...

However, the following code fails its assertion check:

List<string> xs = new List<string>();
ReadOnlyCollection<string> ro = new ReadOnlyCollection<string>(xs);
IList<string> il = ro as IList<string>;
Debug.Assert(il != null);

Could you post a short but complete program that demonstrates that?
Here's one which seems to go against it:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

class Test
{
static void Main()
{
List<string> xs = new List<string>();
ReadOnlyCollection<string> ro =
new ReadOnlyCollection<string>(xs);
IList<string> il = ro as IList<string>;
Console.WriteLine (il != null);
}
}

That prints out "True" as expected.
In a similar vein, the following code fails to compile because, it
claims, ReadOnlyCollection<string> doesnt implement the Insert method.
How is this possible? Insert is part of IList<T>, which
ReadOnlyCollection<T> inherits from, so it should be there!

ro.Insert(0,"hello");

No, it shouldn't - ReadOnlyCollection implements IList<T>.Insert
explicitly, so it's only "there" when you're using the
ReadOnlyCollection as an IList<T>. In other words, you can do:

((IList said:
I wonder if ReadOnlyCollection really does implement those interfaces,
but somehow *hides* the Insert method &c.? How is this done in C#? The
documentation specifically says that methds from interfaces must be
public, so I don't know.

Search for "explicit interface implementation". Basically, instead of:

public void MethodName(...);

you do

void InterfaceName.MethodName(...);
 
Ad

Advertisements

L

Lucian Wischik

Jon Skeet said:
... Search for "explicit interface implementation".

Okay, I understand now. Thanks for the prompt and helpful answer.

Could you post a short but complete program that demonstrates that?

No -- it was a mistake on my part, caused by stopping the debugger AT
the cast rather than after it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top