« VSIP 2005: Managed VSPackagesDelegate calls vastly sped up in .NET 2 »

Be careful when creating a collection from another list

02/09/05

Permalink 01:56:14 pm
Categories: General, Programming, .NET

Be careful when creating a collection from another list

In a project on which I'm currently working, I had these classes:

class MultiCriteria : Criteria {
  public MultiCriteria(params Criteria[] criteria) {
    criteriaList = new BindingList<Criteria>(criteria);
  }

  private BindingList<Criteria> criteriaList;
  public BindingList<Criteria> CriteriaList {
    get { return criteriaList; }
    set { criteriaList = value; }
  }
}

class AllCriteria : MultiCriteria {
  public AllCriteria() { }
  public AllCriteria(params Criteria[] criteria) : base(criteria) { }
}

If you can already spot the problem, no need to read on. If not, this is what happened: at some later point in the application, I was trying to add criteria to the existing list in an AllCriteria instance, and a NotSupportedException was thrown. Why was that?

As it turns out, the BindingList<T> is derived from Collection<T>, both of these classes have a constructor that takes an IList<T>. So far, no problem - this was what I was trying to use by passing the given criteria down into the BindingList<T> constructor. But I assumed that the given list would be used to initialize the collection, instead the list is used by the Collection<T> implementation as its collection!

So what was happening is this: I was constructing my AllCriteria with its default constructor. Although this doesn't explicitely call any base class constructor, the base class constructor that takes the params array is apparently sufficient for the compiler not to complain, and this constructor is called on the base class with an array of type Criteria[], but with a length of zero. The Collection<T> finally gets the IList<T> from the array implementation passed in and simply uses this as its own collection. So the result is, obviously, that my freshly constructed binding list is completely empty and readonly - just like the empty Criteria[] array.

The warning is: Be careful what you pass to the constructors of collection types that are derived from Collection<T>! In contrast to the ArrayList and even the List<T>, which have similar constructors but actually copy the information that gets passed in, the data will directly be used by the newly constructed type.

This was tested with VS 2005 beta 2.

No feedback yet

Leave a comment


Your email address will not be revealed on this site.
(Line breaks become <br />)
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Please complete the song title below. Hint: enter 's', 'a', 't', 'i', 's', 'f', 'a', 'c', 't', 'i', 'o', 'n'
antispam test

Enter your email address:

Search

Oliver
MVP logo
August 2014
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31