Properties must not return arrays

Yes, I know that this has been discussed many times before, and I read all the posts and comments on this subject, but still can not understand something.

One of the options that MSDN offers to solve this violation is to return the collection (or the interface that the collection implements) when accessing the property, however, this obviously does not solve the problem, because most collections are not immutable and can also be changed.

Another possibility that I saw in the answers and comments on this question is to encapsulate the array using ReadOnlyCollection and return it or the base interface (e.g. IReadOnlyCollection), but I don't understand how this solves the performance issue.

If at any time it refers to a property, it needs to allocate memory for a new ReadOnlyCollection that encapsulates the array, so what is the difference (in the form of performance problems, and not for editing an array / collection) than just returning a copy of the original array?

In addition, ReadOnlyCollection has only one constructor with an IList argument, so you need to wrap an array with a list before creating it.

If I intentionally want to work with an array inside my class (not as an immutable collection), is performance better when I allocate new memory for ReadOnlyCollection and encapsulate my array with it instead of returning a copy of the array?

Please clarify this ...

+5
source share
2 answers

If at any time it refers to a property, it needs to allocate memory for a new ReadOnlyCollection that encapsulates the array, so what is the difference (in the form of performance problems, and not for editing an array / collection) than just returning a copy of the original array?

A ReadOnlyCollection<T> wraps the collection - it does not copy the collection.

Consider:

 public class Foo { private readonly int[] array; // Initialized in constructor public IReadOnlyList<int> Array => array.ToArray(); // Copy public IReadOnlyList<int> Wrapper => new ReadOnlyCollection<int>(array); // Wrap } 

Imagine your array contains a million entries. Consider the amount of work that the Array property should have — it should get a copy of just a million records. Consider the amount of work that the Wrapper property needs to perform - it must create an object that simply contains a link.

In addition, if you do not mind a small additional memory hit, you can do this once:

 public class Foo { private readonly int[] array; // Initialized in constructor private readonly IReadOnlyList<int> Wrapper { get; } public Foo(...) { array = ...; Wrapper = new ReadOnlyCollection<int>(array); } } 

Now access to the Wrapper property does not imply any allocation at all - it does not matter if all the callers see the same shell because they cannot mutate it.

+9
source

You do not need to copy the array, just return it as IReadOnlyCollection<T> :

  public class MyClass { private int[] myArray = ... public IReadOnlyCollection<int> MyArray { get { return myArray; } } } 
+1
source

Source: https://habr.com/ru/post/1237331/


All Articles