This topic has not yet been rated - Rate this topic

List<T>.AsReadOnly Method

Returns a read-only IList<T> wrapper for the current collection.

Namespace:  System.Collections.Generic
Assembly:  mscorlib (in mscorlib.dll)
public ReadOnlyCollection<T> AsReadOnly()

Return Value

Type: System.Collections.ObjectModel.ReadOnlyCollection<T>
A ReadOnlyCollection<T> that acts as a read-only wrapper around the current List<T>.

To prevent any modifications to List<T>, expose List<T> only through this wrapper.

A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes.

This method is an O(1) operation.

The following code example demonstrates the AsReadOnly method. A List<T> of strings with a capacity of 4 is created, because the ultimate size of the list is known to be exactly 4. The list is populated with four strings, and the AsReadOnly method is used to get a read-only IList<T> generic interface implementation that wraps the original list.

An element of the original list is set to "Coelophysis" using the Item property (the indexer in C#), and the contents of the read-only list are displayed again to demonstrate that it is just a wrapper for the original list.


using System;
using System.Collections.Generic;

public class Example
{
    public static void Main()
    {
        List<string> dinosaurs = new List<string>(4);

        Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity);

        dinosaurs.Add("Tyrannosaurus");
        dinosaurs.Add("Amargasaurus");
        dinosaurs.Add("Mamenchisaurus");
        dinosaurs.Add("Deinonychus");

        Console.WriteLine();
        foreach(string s in dinosaurs)
        {
            Console.WriteLine(s);
        }

        Console.WriteLine("\nIList<string> roDinosaurs = dinosaurs.AsReadOnly()");
        IList<string> roDinosaurs = dinosaurs.AsReadOnly();

        Console.WriteLine("\nElements in the read-only IList:");
        foreach(string dinosaur in roDinosaurs)
        {
            Console.WriteLine(dinosaur);
        }

        Console.WriteLine("\ndinosaurs[2] = \"Coelophysis\"");
        dinosaurs[2] = "Coelophysis";

        Console.WriteLine("\nElements in the read-only IList:");
        foreach(string dinosaur in roDinosaurs)
        {
            Console.WriteLine(dinosaur);
        }
    }
}

/* This code example produces the following output:

Capacity: 4

Tyrannosaurus
Amargasaurus
Mamenchisaurus
Deinonychus

IList<string> roDinosaurs = dinosaurs.AsReadOnly()

Elements in the read-only IList:
Tyrannosaurus
Amargasaurus
Mamenchisaurus
Deinonychus

dinosaurs[2] = "Coelophysis"

Elements in the read-only IList:
Tyrannosaurus
Amargasaurus
Coelophysis
Deinonychus
 */


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
AsReadOnly does work as it should...

The last comment is a bit misleading as I think the author does not fully understand the C# object model. The ReadOnlyCollection<T> wrappes DOES prevent any modifictions to the collection itself in that you cannot add/remove/insert elements nor can you change any elements using indexing (i.e. someCollection[1] = null).

The author is expecting the ReadOnlyCollection<T> wrapper to prevent modification through accessible members/set properties of non-value objects (classes) within the list. The ReadonlyCollection<T> wrapper cannot prevent that nor should it as that would go against the C# lanuage model. Thus the ReadOnlyCollection<T> wrapper returned by AsReadOnly works exactly like it should.

To prevent changes on objects in the list from being modified one should contruct the class accordingly with the approriate access on members, using readonly on public members, using get-only properties, etc. If this is a library for 3rd party use and the class is only created by the library (the end user doesn't need to create it) then a class with all readonly members and only internal constructors would achieve this. Another option is to use a struct which, as a value object, its properties cannot be set through a collection indexer because the value comes from a get property. For example:

List<Point> list = new List<Point>(new Point[] { new Point(0, 0) });
list[0].X = 1;

The second statement will not compile because Point is a struct and the value from list[0] is from a Get property. The ReadOnlyCollection<Point> returned from the above list.AsReadOnly() would be read only for both the collection and all values within the structs in the collection.

AsReadOnly is Only Partially Read Only
The ReadOnlyCollection<T> type returned by AsReadOnly() simply prevents the length of the list from being changed.  It does not prevent the existing contents of itself or the original list from being modified;  Any changes made to existing elements of the returned ReadOnlyCollection<T> instance, will cause the same changes on the original List<T> as well.