Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to have an array or list returned as a property in .NET?

Tags:

I was reading some of the documentation on MSDN concerning do's and don't with regards to whether something should be implemented as a property or as a method. I ran into one rule in particular that I have a question about.

If "The operation returns an array" use a method (instead of a property).

The page is here: Choosing Between Properties and Methods

Use a method where the operation returns an array because to preserve the internal array, you would have to return a deep copy of the array, not a reference to the array used by the property. This fact, combined with the fact that developers use properties as though they were fields, can lead to very inefficient code.

I understand that the get method of the property would return a reference to the array, which would allow the array to be changed even if there is no set. In the example they give, they are making a deep copy of the array every time the property is accessed, I guess to avoid the possibility of this happening, and this in turn is very inefficient.

It would not be inefficient if the property just returned the reference, and didn't do all the copying, right? And also using a method instead of a property is not going to automatically protect the list from being modified. It is pretty much the same scenario, you would still need a deep copy.

Is using a property and just returning the reference to the array always bad practice? What if you want the caller to be able to modify the array, or you do not care if they modify it? Is it still bad and why, and if so what would be the proper way to allow the caller to modify?

like image 542
Chris Mullins Avatar asked Aug 10 '11 19:08

Chris Mullins


People also ask

Why properties should not return arrays?

Arrays returned by properties are not write-protected, even if the property is read-only. To keep the array tamper-proof, the property must return a copy of the array. Typically, users won't understand the adverse performance implications of calling such a property.

Can an array be a property?

Array properties also exist. These are properties that accept an index, just as an array does. The index can be one-dimensional, or multi-dimensional. In difference with normal (static or dynamic) arrays, the index of an array property doesn't have to be an ordinal type, but can be any type.

Should I use a list or an array?

Arrays can store data very compactly and are more efficient for storing large amounts of data. Arrays are great for numerical operations; lists cannot directly handle math operations. For example, you can divide each element of an array by the same number with just one line of code.

Is it better to use array or list C#?

In general, it's better to use lists in C# because lists are far more easily sorted, searched through, and manipulated in C# than arrays. That's because of all of the built-in list functionalities in the language.


1 Answers

Can you allow the caller to modify an internal array through a property? Yes, of course, but you will take on a slew of possible issues. How you handle those issues and what you can live with is up to you.

The MSDN advice is correct in a very strict sense. That said I have seen List<T> and T[] properties returned before from classes. If your class is a very simple POCO, this is not a big issue because then those classes are just raw data and there's no real business logic to affect.

That said, if I'm returning a list, and I don't want anyone to mess with the internal list, I either return a deep copy every time, or a ReadOnlyCollection, or an iterator. For example, there's lots of places I cache web service request calls, and when i return a cache item, I do NOT want the caller modifying that data or they'll modify what I'm caching. Thus there I make deep copies (which is still faster than the overhead of the web service call).

You just have to know whether your usage requires the safety or not. Is the class only for internal consumption? Or is it designed to be consumed by a wider audience and you have no idea what they are going to do with it? Those type of questions may drive your response.

Sorry for a "it depends" answer, but it truly does depend on what your goal is and if the internals of the class are sensitive to change.

UPDATE You can also return an iterator, I'd avoid returning IEnumerable as a superclass up-cast because it can be cast back down, but if you return an iterator instead (like using Skip(0)) you are safe (aside from still being able to modify the contained objects of course).

For example:

public IEnumerable<T> SomeList  {     get { return _internalList.Skip(0); } } 

Is better than:

public IEnumerable<T> SomeList {     get { return _internalList; } } 

Because the later can still be cast back to List<T> or whatever it was, while the first is an iterator and can't be modified.

like image 102
James Michael Hare Avatar answered Dec 06 '22 19:12

James Michael Hare