While reviewing code, I’ve noticed that many developers adopt a class design where properties return arrays, commonly seen with arrays of bytes. According to Microsoft guidelines, there are compelling reasons to avoid properties that return arrays:
- Lack of Control: Exposing an array through a property grants direct access to the array, enabling clients to modify its elements without encapsulation or control. This violates the principle of encapsulation, making code maintenance and comprehension more challenging.
- Inability to Enforce Read-Only Access: Properties are often utilized to expose an object’s state, and there are cases where read-only access is desirable. However, with an array property, ensuring that the array is only readable and not modifiable becomes problematic.
- Limited Flexibility for Future Changes: If internal data representation needs to be altered (e.g., transitioning from an array to a List), using a property returning an array may result in breaking changes for client code.
While I concur with these points, it’s crucial to consider the impact on performance and memory allocation. The following example illustrates the associated issues:
private readonly Person<Address>[] _personArray;
// Property Example
public Person<Address>[] PersonArray => this._personArray;
It is recommended to either return the array from a method or use a Collection<>
, as demonstrated in this example:
private readonly Person<Address>[] _personArray;
private readonly Collection<Person<Address>>
_personCollection;
// Return array via method.
public Person<Address>[] GetPersonArray()
{
return this._personArray;
}
// Return Colleciton via method.
public Collection<Person<Address>> GetPersonCollection()
{
return this._personCollection;
}
// Return Collection via Property
public Collection<Person<Address>> PersonCollection => this._personCollection;
Now let’s look at the performance.
Benchmark Results
I conducted initial tests using a reference type. As evident from the results, returning an array of 1,000 items through a property proves to be more efficient and incurs the least memory allocation.
Allocations: Property Array: 3,953,272 bytes, Method Array: 8,022,696 bytes, Method Collection: 7,971,856 bytes.
I was curious about the performance of value types. As observed in the results, returning an array via a property once again is the most efficient option, with the least memory allocation.
Allocations: Property Array: 3,992,760 bytes, Method Array: 7,910,488 bytes, Method Collection: 7,901,296.
I recommend adhering to Microsoft’s guidance unless performance is of critical importance.
This is how I have it setup checking for this issue in my EditorConfig: dotnet_diagnostic.CA1819.severity = suggestion
Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks
Make a one-time donation
Make a monthly donation
Make a yearly donation
Choose an amount
Or enter a custom amount
Your contribution is appreciated.
Your contribution is appreciated.
Your contribution is appreciated.
DonateDonate monthlyDonate yearlyIf you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave
© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.