26

I ran a security code analyst i found myself having a CA2105 warning. I looked at the grade tampering example. I didn't realize you can assign int[] to a readonly int. I thought readonly was like the C++ const and makes it illegal.

The How to Fix Violations suggest i clone the object (which i don't want to do) or 'Replace the array with a strongly typed collection that cannot be changed'. I clicked the link and see 'ArrayList' and adding each element one by one and it doesn't look like you can prevent something adding more.

So when i have this piece of code what is the easiest or best way to make it a read only collection?

public static readonly string[] example = { "a", "b", "sfsdg", "sdgfhf", "erfdgf", "last one"};
John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • possible duplicate of [Return collection as read-only](http://stackoverflow.com/questions/55502/return-collection-as-read-only) – nawfal Nov 11 '13 at 11:01
  • A readOnlyCollection = Normal collection - Add/remove APIs - Set Indexer – RBT Feb 20 '17 at 01:56

6 Answers6

42

The easiest way to have a collection which you cannot modify is to use

ReadOnlyCollection

Example from MSDN:

List<string> dinosaurs = new List<string>();
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Deinonychus");
dinosaurs.Add("Compsognathus");

ReadOnlyCollection<string> readOnlyDinosaurs = new ReadOnlyCollection<string>(dinosaurs);
Mikael Svenson
  • 39,181
  • 7
  • 73
  • 79
13
public static readonly ReadOnlyCollection<string> example
    = new ReadOnlyCollection<string>(new string[] { "your", "options", "here" });

(although it should still probably be exposed as a get property rather than a public field)

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    I would second here on using the `readonly` keyword for the variable as well. Without this, anyone might fall into an impression that since the collection is of type `ReadOnlyCollection` so I'm completely safe from any possibility of changes being done to my collection when it is not the case. One might not realize that the collection is read-only but the variable pointing to it is not. What a `ReadOnlyCollection` would mean if I can reassign the variable itself to a new collection altogether. +1. – RBT Feb 17 '17 at 01:44
  • 1
    @RBT note that readonly is a lie; readonly fields can absolutely be mutated. You have to cheat a little, of course... – Marc Gravell Feb 17 '17 at 02:01
  • It took me a while to digest [this](http://stackoverflow.com/questions/6722571/c-sharp-and-immutability-and-readonly-fields-a-lie). Thank you for showing me the light. – RBT Feb 22 '17 at 23:56
12

If you're working with arrays, you can use

return Array.AsReadOnly(example);

to wrap your array in a read-only collection.

Steve Dennis
  • 1,343
  • 10
  • 10
3
var readOnly = new ReadOnlyCollection<string>(example);
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
1

I was looking for a similar solution, but I wanted to still be able to modify the collection from inside the class so I chose the option outlined here: http://www.csharp-examples.net/readonly-collection/

In short, his example is:

public class MyClass
{
    private List<int> _items = new List<int>();

    public IList<int> Items
    {
        get { return _items.AsReadOnly(); }
    }
}
TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
nelsonmichael
  • 119
  • 1
  • 4
1
ReadOnlyCollection<string> readOnlyCollection = 
            new ReadOnlyCollection<string>(example);
Kyle Rosendo
  • 25,001
  • 7
  • 80
  • 118