Exposing a Generic List

by KodefuGuru 30. September 2008 18:35

You're writing a Customer class, and the Customer class contains a collection of Account objects. Because you want to add and remove accounts with ease, you implement this collection as a List<T>.

    public class Customer
    {
        
private List<Account> accounts = new List<Account>();

        
public List<Account> Accounts
        {
            
get { return accounts; }
        }
    }

Life is good. Your tests iterate through the accounts, add new accounts, and remove accounts. However, when you run FxCop, it complains that you shouldn't expose generic lists.

Do not expose List<T> in object models. Use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> instead. List<T> is meant to be used from implementation, not in object model API. List<T> is optimized for performance at the cost of long term versioning. For example, if you return List<T> to the client code, you will not ever be able to receive notifications when client code modifies the collection.

FxCop is correct in its assessment as it becomes more difficult to later add underlying functionality. But I feel that it leaves out an important point. You shouldn't expose too much about your implementation, and this relays to the world that Customer uses a List<T>. Consumers of the Employee class don't care that you've implemented List<T>, they only care about the interface. Expose the public property as the interface the consumer should be using. In this example, our consumers want to utilize the interface IList<T>. Refactoring this is pretty easy: modify the property to be IList<Account>.

    public class Customer
    {
        
private List<Account> accounts = new List<Account>();

        
public IList<Account> Accounts
        {
            
get { return accounts; }
        }
    }

In other cases, the consumers may only want to iterate the collection without making modifications. In that situation, expose the list as IEnumerable<T>. The point is to take into account the interface that consumers want to utilize, then hide your implementation.

You shouldn't do it this way if the collection needs to be serialized. In that case, stick with one of the concrete classes such as Collection<T> like FxCop suggested.

Tags: , ,

Kodefu

Comments

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

Whois KodefuGuru

Chris Eargle

Chris Eargle
.NET Community Champion

LinkedIn Twitter Technorati Facebook

MVP - Visual C#

 

INETA Community Champions
Friend of RedGate
Telerik .NET Ninja
Community blogs & blog posts

I am a #52er


World Map

RecentComments

Comment RSS

Tag cloud

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010