Visual Studio 2005 December CTP - BindingList problem

Tuesday, January 4th, 2005 @ 5:11 am | Development

I've installed the
December CTP of Visual Studio 2005
and have run into what I consider to
be a bug in the BindingList<T> class. Aside from having moved
namespaces again since the November
CTP, it now requires that any class derived from it exposes its generic argument
as the first in the list.

For example, BindingList<T> makes it easy to build objects that
contain other objects (and still expose change events for the contents, a feature
which is lacking from the other collection classes). In Beta 1 and the November
CTP you could easily build a tree with a class derived from BindingList<T>
like this:

// Interface common to all objects which could appear in the tree
public interface ITreeNode : ICollection<ITreeNode>
{
	ITreeNode Parent { get; }
	string Name { get; }
	etc...
}

public class TreeNode : BindingList<ITreeNode>, ITreeNode
{
	...
}

All well and good. However, Reflector
reveals that in the December CTP BindingList<T> has a private
property called ItemTypeHasDefaultConstructor, which starts off with
the following line:

Type type1 = base.GetType().GetGenericArguments()[0];

In the example, GetType() returns the type for the TreeNode
class, which does not have any generic arguments and so the indexer [0]
causes an IndexOutOfRangeException. Because this property is used in
the construction of a BindingList<T> instance it’s not possible
to create an instance of a class derived from BindingList<T>
that does not itself have the same first generic parameter! I’m not overly familiar
with reflection over generic types, but surely it would be possible to find the
first argument for BindingList<T> as it was used in the declaration
of TreeNode?

There’s an obvious workaround, but it’s a pain:

public class TreeNode<T> : BindingList<T>, ITreeNode where T : ITreeNode
{
	...
}

We have to make the TreeNode class generic, too, and every class derived
from it. Not nice! :(

Update (and Workaround)

I exported the code for the BindingList<T> class using Reflector and changed the offending line to this:

Type type1 = typeof(T);

Now instead of trying to get the generic argument type from the current instance type it uses T directly. That’s much better. I won’t post it here, but drop me a line and I’ll gladly send the fixed BindingList<T> C# code to anyone who needs it. You don’t need a fix - it’s already fixed in .NET 2.0!

I’ve reported this as a bug, and the good news is that this has already been fixed!





Comments

Add your opinion to this article and participiate in the discussion, or read more:

Name (required)

Email (required)

Website

Add your comment