Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collection properties should be read only - Loophole?

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?

like image 490
Bob Horn Avatar asked Dec 09 '22 23:12

Bob Horn


1 Answers

Not exposing the setter prevents a situation where the collection is assigned a value of null. There's a difference between null and a collection without any values. Consider:

for (var value in this.myCollection){ // do something

When there are no values (i.e. someone has called Remove on every value), nothing bad happens. When this.myCollection is null, however, a NullReferenceException will be thrown.

Code Analysis is making the assumption that your code doesn't check that myCollection is 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-safe Add and Remove methods.

like image 188
Chris Laplante Avatar answered Dec 11 '22 13:12

Chris Laplante