4

I have two private arrays in a class that runs a certain operation using a method. After this method is called, those two arrays are filled with the results. It's not a good practice to make those arrays properties, so I was planning to have a separate property that returns a clone of the private array.

1) What is the overhead of returning a clone of the array? Is it unnoticeable in every case?

2) I could use an indexer if there was just one array. Is there a specific mechanism to use indexers for more than one array in a class?

hattenn
  • 4,371
  • 9
  • 41
  • 80
  • 6
    You show show the code – cuongle Oct 08 '12 at 08:08
  • 1
    Do you really need to save those arrays inside a class? Wouldnt it be better to directly return the filled arrays? – Euphoric Oct 08 '12 at 08:13
  • The class evaluates and contains the results so I think it's better to keep them in the class. Otherwise, I could just call the method itself and get the result. – hattenn Oct 08 '12 at 08:14
  • That has nothing to do with it. Think of it from point of caller. Do you expect method to return something? Then return it from method. – Euphoric Oct 08 '12 at 08:16
  • There are many variables returned by the method itself, that's why I thought it'd be nice to contain them in a class. And that way if the operation result needs to be copied somewhere else, then I can just copy the instance, rather than copying every variable that was returned by the method. – hattenn Oct 08 '12 at 08:18
  • Then your problem is "How to return many values from method". – Euphoric Oct 08 '12 at 08:20
  • How is that my problem? I solved it using a container for the result. If that's not a good practice somehow, I'd be happy to learn more. – hattenn Oct 08 '12 at 08:22
  • If this turns out to be a performance problem, you will have to consider different types of caching strategies. This will depend on the volatility and update strategy of the underlying data and wether what the expected volume and performance requirements are to the operations writing and reading, respectively. This will decide your overall design and hence the code. It is hard to decide on a code solution without these considerations. – Tormod Oct 08 '12 at 09:04

3 Answers3

3

I think you mean "overhead" or "cost" and not "overload". Anyway, computationally it's O(1) so it depends on the size of tha rray, but generally speaking Array copying is a cheap operation if it's under a thousand elements or so.

If you don't intend on the arrays to be modified then you could expose your private arrays by wrapping them in a ReadOnlyCollection<T> like so:

private TWhatever[] _array;
public ReadOnlyCollection<TWhatever> Elements { get; private set; }

public ClassConstructor() {
    _array = new TWhatever[1000];
    this.Elements = new ReadOnlyCollection<TWhatever>( _array );
}
Dai
  • 141,631
  • 28
  • 261
  • 374
  • When we are initializing the `ReadOnlyCollection`, doesn't it copy the elements of the array somewhere else in the memory? – hattenn Oct 08 '12 at 08:19
2

Cloning an array is a memory allocation; the impact will depend directly on the size of the array.

An indexer is just a method; another approach might be to just add a method such as GetName(int index) and GetValue(int index) (if your arrays are names/values, for example). There aren't inbuilt named indexers in C#, alas.

If performance is important, and you will need to access multiple values, then another approach is to have a method that copies the values to an array the caller supplies, for example GetNames(string[] names, int offset) { this.names.CopyTo(names, offset); }. This can be useful by allowing the caller to allocate a single buffer, and then use it to obtain values from multiple objects - or if you add a few parameters (for the count etc), to obtain the values in batches rather than individually. Whether this is necessary / useful depends a lot on the exact scenario, though.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

Maybe is it possible to do something like this

KeyValuePair this[int i] { get { /* code */ } private set{ /* code */ } }
EaterOfCode
  • 2,202
  • 3
  • 20
  • 33