property - c# getter setter shorthand




How to expose a collection property? (8)

Actually arrays still have one advantage over Collections/Lists. Due to the way that Java implements Generics through type erasure, you cannot have two methods that take Collections as arguments yet only differ by the Collection's generic type.

Ex:

public void doSomething(Collection<String> strs) { ... }
public void doSomething(Collection<Integer> ints) { ... }

The two above methods will not compile because the javac compiler uses type erasure and thus cannot pass the type information to the JVM. The JVM will only see two methods that take a Collection as its argument.

In the above cases, the best work-around is to make the methods take arrays as their arguments and use the Collection/List's toArray() method when passing the arguments to them. If you still want to use Collection/List's inside the above methods, just use java.util.Arrays.asList() method to get your List back.

Ex:

public void doSomething(String[] strs) {
        List<String> strList = Arrays.asList(strs);
        ...
}

public void doSomething(Integer[] ints) {
        List<Integer> intList = Arrays.asList(ints);
        ...
}

public static void main(String[] args) {
        List<String> strs = new ArrayList<String>();
        List<Integer> ints = new ArrayList<Integer>();
        obj.doSomething(strs.toArray());
        obj.doSomething(ints.toArray());
}

Every time I create an object that has a collection property I go back and forth on the best way to do it?

  1. public property with a getter that returns a reference to private variable
  2. explicit get_ObjList and set_ObjList methods that return and create new or cloned objects every time
  3. explicit get_ObjList that returns an IEnumerator and a set_ObjList that takes IEnumerator

Does it make a difference if the collection is an array (i.e., objList.Clone()) versus a List?

If returning the actual collection as a reference is so bad because it creates dependencies, then why return any property as a reference? Anytime you expose an child object as a reference the internals of that child can be changed without the parent "knowing" unless the child has a property changed event. Is there a risk for memory leaks?

And, don't options 2 and 3 break serialization? Is this a catch 22 or do you have to implement custom serialization anytime you have a collection property?

The generic ReadOnlyCollection seems like a nice compromise for general use. It wraps an IList and restricts access to it. Maybe this helps with memory leaks and serialization. However it still has enumeration concerns

Maybe it just depends. If you don't care that the collection is modified, then just expose it as a public accessor over a private variable per #1. If you don't want other programs to modify the collection then #2 and/or #3 is better.

Implicit in the question is why should one method be used over another and what are the ramifications on security, memory, serialization, etc.?


Check out the unmodifiable* methods in Collections class to make returned collections read-only/immutable. This will wrap the original collection in a list that prevents access to changing the list itself (the elements themselves are not immutable though).

unmodifiableList for instance.

For me it depends on how the returned list will be used. What other methods is it being passed to, and how will it be used? In general I'd prefer the generic collection over an array, but would change it on a case by case basis.

The array will probably perform faster as well if you're doing something critical.


I usually go for this, a public getter that returns System.Collections.ObjectModel.ReadOnlyCollection:

public ReadOnlyCollection<SomeClass> Collection
{
    get
    {
         return new ReadOnlyCollection<SomeClass>(myList);
    }
}

And public methods on the object to modify the collection.

Clear();
Add(SomeClass class);

If the class is supposed to be a repository for other people to mess with then I just expose the private variable as per method #1 as it saves writing your own API, but I tend to shy away from that in production code.


If you're simply looking to expose a collection on your instance, then using a getter/setter to a private member variable seems like the most sensible solution to me (your first proposed option).



The Framework Design Guidelines suggest returning a copy of the Array. That way, consumers can't change items from the array.

// bad code
// could still do Path.InvalidPathChars[0] = 'A';
public sealed class Path {
   public static readonly char[] InvalidPathChars = 
      { '\"', '<', '>', '|' };
}

these are better:

public static ReadOnlyCollection<char> GetInvalidPathChars(){
   return Array.AsReadOnly(InvalidPathChars);
}

public static char[] GetInvalidPathChars(){
   return (char[])InvalidPathChars.Clone();
}

The examples are straight from the book.


API java 5 and more: should I return an array or a Collection?

Prefer Collection (or List, or Set as appropriate) to an array. With generics you get the type-checking that was lacking pre-Java 5. Also, by exposing only the interface, you are free to change the implementation later (e.g. switch an ArrayList for a LinkedList).

Arrays and generics don't mix very well. So, if you want to take advantage of generics, you should usually avoid arrays.
I.e: You can't generically create an array. For example, if T is a generic type then "new T[0]" doesn't compile. You'd have to do something like "(T[]) new Object[0]", which generates an unchecked cast warning. For the same reason, you can't use generic types with varargs without warnings.

Using Collections.unmodifiableCollection (and similar methods), you get the read-only constraint (which you can't achieve with an array - you would have to return a clone of the array).

You can't enforce immutability of members, but then you can't do that with an array either.


Are immutable arrays possible in .NET?

ReadOnlyCollection<T> is probably what you are looking for. It doesn't have an Add() method.





architecture