views:

152

answers:

3

Hello. .NET v2

When the List has a very useful (4 me) method AsReadOnly() the LinkedList does not have such a method.

Is there a way to "quickly" interface an internal LinkedList to read only from the external code?

+6  A: 

Why not just return a IEnumerable<T>? If you just want to let users enumerate the list without modifying it*, IEnumerable is the obvious choice.

If you want to have a read only interface of the LinkedList interface, you can wrap LinkedList, forward read only methods to the wrapped list and deny any changes.

*) Keep in mind that neither ReadOnlyCollection not IEnumerable will prevent callers to change state of objects in case of a collection of reference types. If the objects should be read only as well, you need to implement this as part of their type.

Brian Rasmussen
would you explain?
serhio
I assume you want to return a readonly version of your LinkedList. You can do this by returning it as an IEnumerable<T>. This will allow the caller to enumerate the list, but not to modify it.
Brian Rasmussen
what if I would keep the list properties, like First, Last and Next...
serhio
If those methods are important, then you have to wrap LinkedList and basically do what ReadOnlyCollection does.
Brian Rasmussen
You have reason. Unfortunately I not have experience in creating wrappers or what ReadOnlyCollection does. So a little sample would be helpful. Thanks.
serhio
A: 

LinkedList<T> doesn't implement IList so in short, no there is no way of quickly doing it. If you cast your LinkedList to a List you will probably lose the functionality you require.

LinkedList<T> doesn't offer you anything for subclassing so you'll need to write your own. I imagine the next request is "can you show me how to do that"

Chris S
can you show me how to do that?Thanks.
serhio
Is returning a list ok? Or do you need it to be a `LinkedList`
Chris S
I'd prefeer a *Linked* Readonly List
serhio
+4  A: 

ReadOnlyCollection<T> takes an IList<T> as argument to the constructor. LinkedList<T> does not implement this interface. List<T> has a constructor overload that takes an IEnumerable<T> as argument, and LinkedList<T> implements this interface. So the following should work:

LinkedList<int> linked = new LinkedList<int>();
// populate the list

ReadOnlyCollection<int> readOnly = new ReadOnlyCollection<int>(
    new List<int>(linked));

It uses an instance of List<T> to carry the items into the ReadOnlyCollection<T> constructor.

Fredrik Mörk
Worked. Thanks!
serhio
*grumble something about wanting a readonly `LinkedList` not `IList`* (the question, not the answer)
Chris S
Is a pity that in this case I lose the First and Last linked list properties...
serhio
For an unknown reason `LinkedListNode` is sealed and `LinkedList` has no virtual methods so you're stuck to writing your own doubly linked list with immutable nodes
Chris S