.NET Core.NET Framework Acronym Glossary.NET Framework ADO.NET.NET Framework CLR.NET Framework Code Contracts.NET Framework Collections.NET Framework Custom Types.NET Framework DateTime parsing.NET Framework Dependency Injection.NET Framework Dictionaries.NET Framework Encryption / Cryptography.NET Framework Exceptions.NET Framework Expression Trees.NET Framework File Input/Output.NET Framework ForEach.NET Framework Garbage Collection.NET Framework Globalization in ASP.NET MVC using Smart internationalization for ASP.NET.NET Framework HTTP clients.NET Framework HTTP servers.NET Framework Introduction.NET Framework JIT compiler.NET Framework JSON Serialization.NET Framework LINQ.NET Framework Managed Extensibility.NET Framework Memory management.NET Framework Networking.NET Framework NuGet packaging system.NET Framework Platform Invoke.NET Framework Process and Thread affinity setting.NET Framework Reading and writing Zip files.NET Framework ReadOnlyCollections.NET Framework Reflection.NET Framework Regular Expressions (System.Text.RegularExpressions).NET Framework Serial Ports.NET Framework Settings.NET Framework SpeechRecognitionEngine class to recognize speech.NET Framework Stack and Heap.NET Framework Strings.NET Framework Synchronization Contexts.NET Framework System.Diagnostics.NET Framework System.IO.NET Framework System.IO.File class.NET Framework System.Net.Mail.NET Framework System.Reflection.Emit namespace.NET Framework System.Runtime.Caching.MemoryCache (ObjectCache).NET Framework Task Parallel Library (TPL).NET Framework Task Parallel Library (TPL) API Overviews.NET Framework Threading.NET Framework TPL Dataflow.NET Framework Unit testing.NET Framework Upload file and POST data to webserver.NET Framework Using ProgressT and IProgressT.NET Framework VB Forms.NET Framework Work with SHA1 in C Sharp.NET Framework Write to and read from StdErr stream.NET Framework XmlSerializerJSON in .NET with Newtonsoft.JsonParallel processing using .NET framework

.NET Framework ReadOnlyCollections

From WikiOD

Remarks[edit | edit source]

A ReadOnlyCollection provides a read-only view to an existing collection (the 'source collection').

Items are not directly added to or removed from a ReadOnlyCollection. Instead, they are added and removed from the source collection and the ReadOnlyCollection will reflect these changes to the source.

The number and order of elements inside a ReadOnlyCollection cannot be modified, but the properties of the elements can be and the methods can be called, assuming they are in scope.

Use a ReadOnlyCollection when you want to allow external code to view your collection without being able to modify it, but still be able to modify the collection yourself.

See Also

  • ObservableCollection<T>
  • ReadOnlyObservableCollection<T>

ReadOnlyCollections vs ImmutableCollection[edit | edit source]

A ReadOnlyCollection differs from an ImmutableCollection in that you cannot edit an ImmutableCollection once you created it - it will always contain n elements, and they cannot be replaced or reordered. A ReadOnlyCollection, on the other hand, cannot be edited directly, but elements can still be added/removed/reordered using the source collection.

Creating a ReadOnlyCollection[edit | edit source]

Using the Constructor[edit | edit source]

A ReadOnlyCollection is created by passing an existing IList object into the constructor:

var groceryList = new List<string> { "Apple", "Banana" };
var readOnlyGroceryList = new ReadOnlyCollection<string>(groceryList);

Using LINQ[edit | edit source]

Additionaly, LINQ provides an AsReadOnly() extension method for IList objects:

var readOnlyVersion = groceryList.AsReadOnly();

Note[edit | edit source]

Typically, you want to maintain the source collection privately and allow public access to the ReadOnlyCollection. While you could create a ReadOnlyCollection from an in-line list, you would be unable to modify the collection after you created it.

var readOnlyGroceryList = new List<string> {"Apple", "Banana"}.AsReadOnly();
// Great, but you will not be able to update the grocery list because 
//  you do not have a reference to the source list anymore!

If you find yourself doing this, you may want to consider using another data structure, such as an ImmutableCollection.

Updating a ReadOnlyCollection[edit | edit source]

A ReadOnlyCollection cannot be edited directly. Instead, the source collection is updated and the ReadOnlyCollection will reflect these changes. This is the key feature of the ReadOnlyCollection.

var groceryList = new List<string> { "Apple", "Banana" };

var readOnlyGroceryList = new ReadOnlyCollection<string>(groceryList);

var itemCount = readOnlyGroceryList.Count;  // There are currently 2 items

//readOnlyGroceryList.Add("Candy");         // Compiler Error - Items cannot be added to a ReadOnlyCollection object
groceryList.Add("Vitamins");                // ..but they can be added to the original collection

itemCount = readOnlyGroceryList.Count;      // Now there are 3 items
var lastItem = readOnlyGroceryList.Last();  // The last item on the read only list is now "Vitamins"

View Demo

Warning: Elements in a ReadOnlyCollection are not inherently read-only[edit | edit source]

If the source collection is of a type that is not immutable, elements accessed through a ReadOnlyCollection can be modified.

public class Item
    public string Name { get; set; }
    public decimal Price { get; set; }

public static void FillOrder()
    // An order is generated
    var order = new List<Item>
        new Item { Name = "Apple", Price = 0.50m },
        new Item { Name = "Banana", Price = 0.75m },
        new Item { Name = "Vitamins", Price = 5.50m }

    // The current sub total is $6.75
    var subTotal = order.Sum(item => item.Price);

    // Let the customer preview their order
    var customerPreview = new ReadOnlyCollection<Item>(order);

    // The customer can't add or remove items, but they can change 
    //   the price of an item, even though it is a ReadOnlyCollection
    customerPreview.Last().Price = 0.25m;

    // The sub total is now only $1.50!
    subTotal = order.Sum(item => item.Price);

View Demo