In the process of adhering to code analysis errors, I’m changing my properties to have private setters. Then I started trying to understand why a bit more. From some research, MS says this:
A writable collection property allows a user to replace the collection with a completely different collection.
And the answer, here, states:
Adding a public setter on a
List<T>object is dangerous.
But the reason why it’s dangerous is not listed. And that’s the part where I’m curious.
If we have this collection:
public List<Foo> Foos { get; set; }
Why make the setter private? Apparently we don’t want client code to replace the collection, but if a client can remove every element, and then add whatever they want, what’s the point? Is that not the same as replacing the collection entirely? How is value provided by following this code analysis rule?
Not exposing the setter prevents a situation where the collection is assigned a value of
null. There’s a difference betweennulland a collection without any values. Consider:for (var value in this.myCollection){ // do somethingWhen there are no values (i.e. someone has called
Removeon every value), nothing bad happens. Whenthis.myCollectionis null, however, aNullReferenceExceptionwill be thrown.Code Analysis is making the assumption that your code doesn’t check that
myCollectionis null before operating on it.It’s probably also an additional safeguard for the thread-safe collection types defined in
System.Collections.Concurrent. Imagine some thread trying to replace the entire collection by overwritting it. By getting rid of the public setter, the only option the thread has is to call the thread-safeAddandRemovemethods.