ReadOnlyCollections
Creating a ReadOnlyCollection
Section titled “Creating a ReadOnlyCollection”Using the Constructor
Section titled “Using the Constructor”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
Section titled “Using LINQ”Additionaly, LINQ provides an AsReadOnly() extension method for IList objects:
var readOnlyVersion = groceryList.AsReadOnly();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
Section titled “Updating a ReadOnlyCollection”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 objectgroceryList.Add("Vitamins"); // ..but they can be added to the original collection
itemCount = readOnlyGroceryList.Count; // Now there are 3 itemsvar lastItem = readOnlyGroceryList.Last(); // The last item on the read only list is now "Vitamins"Warning: Elements in a ReadOnlyCollection are not inherently read-only
Section titled “Warning: Elements in a ReadOnlyCollection are not inherently read-only”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);}Remarks
Section titled “Remarks”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
Section titled “ReadOnlyCollections vs ImmutableCollection”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.