1

I have an array of valid string values like this:

string[] validValues = new string[] {"none","all","some"};

I have a method that validates a user's selection in a drop down box like this:

bool valid = validValues.Contains( selection );

I don't want to re-create the validValues array every time this method is called, so I'd like to assign it to a static readonly property. The array itself is immutable. Is this scenario thread-safe? This is part of an MVC controller method, so it's quite possible that multiple threads will be accessing the array via the Enumerable<string>.Contains method at the same time.

If the enumeration is not thread safe, then would it be thread safe to use a method like Array.IndexOf instead? Decompiling shows that the method either calls the native method TrySZIndexOf, or it iterates over the array by index. From what I've read here, that may be safe? I'd just rather use Contains because it conveys what's trying to be accomplished more clearly than IndexOf() == -1.

Community
  • 1
  • 1
Triynko
  • 18,766
  • 21
  • 107
  • 173
  • 8
    Yes, iterating over it is completely thread safe as long as the array never changes. You may want to use an immutable `HashSet` instead though, that way you won't need the iteration. – Joachim Isaksson Feb 22 '16 at 17:15
  • Yes, since it is read only – Ian Feb 22 '16 at 17:19
  • As @JoachimIsaksson said, a hash set will be faster for actually doing your look-ups, and you can delcare `validValues` as an `IReadOnlyCollection` to signal the immutable nature of the collection. – Preston Guillot Feb 22 '16 at 17:22
  • AS IT IS WRITTEN in your first two code quotes, certainly not. IF indeed you add readonly as you mention - then yes. (As everyone has mentioned, use a readonly HashSet here) – Fattie Feb 22 '16 at 17:52
  • Your specific scenario -- immutable array, initialized in a readonly static field -- sounds quite threadsafe. However, be cautious in extrapolating from this fact; people occasionally get into a bad way when they incorrectly think that everything in a static initializer becomes threadsafe by magic. If you want to know what static initializers actually do, a good place to start your researches is here: http://stackoverflow.com/questions/9398509/how-does-a-static-constructor-work/9399027#9399027 – Eric Lippert Feb 22 '16 at 19:10

2 Answers2

2

Yes, this access is thread safe (assuming array is never modified).

You can also use standard Dictionary or HashSet if it works better as both are also safe for read-only multithreaded access.

If you concerned that one can change array by mistake - consider using new Immutable types like ImmutableList.


Generic discussion that covers the resononing - Why are immutable objects thread-safe?. Additionally there is series of articles by Eric Lippert on immutable data structures, and Read-only and theradsafe touches on topic of such access.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0

Yes. As you are declaring it as read only, it is thread safe.

You may use ReadOnlyCollection class in C# rather declaring an array as read only.

https://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx

superboy
  • 97
  • 1
  • 2
  • 15
  • 1
    The `readonly` field modifier and the `ReadOnlyCollection` type do not mean the same thing, and it's important not to confuse them. The `readonly` field modifier guarantees that the value of the *field* does not change. For a collection (or any other reference type), this means that you cannot assign an entirely new collection to the member - but you can freely modify the collection the member points to. `ReadOnlyCollection`s guarantee that elements of the collection do not change, i.e. `collection[0]` cannot become a different object. – Preston Guillot Feb 22 '16 at 18:04