Extend BindingList with filter functionality

If you still work with windows forms and cannot move all of your projects to WPF, you probably gets annoyed by the limitation of the standard BindingList<T> included in the framework. In an old post I showed how can you create a specialized BindingList<T> to support generic Find() thanks to reflection, but this is not enough.

Another annoying limitation is that BindingList does not support IBindingListView. For those that does not knows this interface, it is the one used by the windows forms binding engine to support filtering and advanced sorting. I think that filtering is a real basic functionality needed by the binding engine, and in fact WPF support for filtering, sorting and grouping, make these operations really a breeze. But BindingList does not offers such a functionality.

My question is: is it possible to inherits from BindingList<T> adding generic filtering support as for the DataView component?. The answer is yes, here is a simple implementation.

public string Filter { get { return filterClause; } set { if (filterClause == value) return; filterClause = value; DoFilter(); } }

This is really simple, I implement the FIlter property with a simple check, if the filterClause changes, I call the DoFilter function.

private Func<T, Boolean> filterPredicate; private List<T> original = new List<T>(); private void DoFilter() { if (String.IsNullOrEmpty(filterClause)) { Items.Clear(); original.ForEach(e => Items.Add(e)); } else { original.Clear(); original.AddRange(Items); Items.Clear(); filterPredicate = DynamicLinq.ParseToFunction<T, Boolean>(filterClause); foreach (T element in original.Where(filterPredicate)) Items.Add(element); } }

The implementation is based on this standard trick, if a filter is applied I copy all the elements in a temp list, then clear the base.Items list and add again only the elements that satisfies the filter. The big work is done in DynamicLinq.ParseToFunction that takes a string and dynamically compiles a function with that criteria. Here is a simple test showing this class in action.

[Test] public void TestLogicAnd() { Func<Customer, Boolean> f = DynamicLinq.ParseToFunction<Customer, Boolean>("Name == 'Gian Maria' && Age > 5"); Assert.That(f(aCustomer), Is.True); }

Actually I use three main component, a tokenizer that takes a string and separates into token, then I pass the tokenized expression (is a List<String>) to another component that convert the infix form in postfix form (reverse Polish), finally I create an expression from the reverse Polish form, creates a LambdaExpression on it and finally call compile() to make dynamic generation happens. The result is a dynamic generator of LINQ expression from a string. It still misses a lot, you cannot express condition on nested properties and parameter support is still experimental, but the basic is there.

The code is still under development, if you are curios you can check out the repository at http://dotnetmarcheproject.googlecode.com/svn/trunk the code is still in rough form, but if you like it you can give it a shot. The class is the BindingListExt<T>

Alk.

Tags:

Story of a stupid bug, difference between struct and class

I’ve incurred in a very stupid bug this afternoon, I run test on a new version of a component and I see that a lot of exceptions are raised about violating unique constraint of a simple strongly typed dataset I use to log information in database.

After a brief look at the code I found that I create new guid with the instruction new Guid(), I was really surprised because I really know that new guid should be created with Guid.NewGuid(). This is indeed caused by the fact that Guid() is a structure and not a class. The following test demonstrate this fact

[Test] public void CreateGuid() { Assert.That(new Guid(), Is.EqualTo(Guid.Empty)); Assert.That(Guid.NewGuid(), Is.Not.EqualTo(Guid.Empty)); }

This test will succeeds because Guid is a value type, and he always has a default constructor that can be called to create empty instance of the structure. If you look into the documentation of Guid you can in fact verify that default constructor is not even listed between the valid ones.

This is one of the most annoying difference from reference and value type: value type always have a default constructor and you cannot prevent the user to use it.

alk.

Tags:

A generic IComparer that works with reflection

Today I was speaking with a colleague about creating a generic IComparer<T> that is able to compare two object based on a property discovered through reflection. Such object will be very useful to sort or find object inside collection of objects when you work with a domain model. In a domain we usually have a lot of objects such as customer, order, and so on, and it happens to have an homogeneous collection of objects in memory that needs to be sorted. Implementing an IComparer object for each combination of property and type is really boring so it useful to create a class capable to compare object based on reflection. A first implementation of the IComparer<T>::Compare() method could be the following

publicテつ intテつCompare(Tテつx,テつTテつy)テつ{テつテつテつテつ
テつテつテつテつテつPropertyInfoテつpropertyInfoテつ=テつ
typeof(T).GetProperty(SortColumn);
テつテつテつテつテつ
IComparableテつobj1テつ=テつ(IComparable)propertyInfo.GetValue(x,テつ null);
テつテつテつテつテつ
IComparableテつobj2テつ=テつ(IComparable)propertyInfo.GetValue(y,テつ null);
テつテつテつテつテつ
returnテつ(obj1.CompareTo(obj2));
}

This implementation works as expected, but it has bad performance, this because it use reflection to find propertyInfo at each calls of the Compare() method. Since we are dealing with homogeneous collections I know in advance that the collection contains objects of a same type, so a better strategy is to cache the MethodInfo related to the GetterPart of the property into the constructor of the comparer object.

テつテつテつ publicテつ classテつ GenericIComparer<T>テつ:テつ IComparer<T>テつ{
テつ
テつテつテつテつテつテつ
privateテつ readonlyテつ MethodBaseテつmethodInfo;
テつ
テつテつテつテつテつテつ
internalテつGenericIComparer(MethodBaseテつmethodInfo,テつ Booleanテつreversed)テつ{
テつテつテつテつテつテつテつテつテつ
this.methodInfoテつ=テつmethodInfo;
テつテつテつテつテつテつテつテつテつmReversedテつ=テつreversed;
テつテつテつテつテつテつ}
テつ
テつテつテつテつテつテつ
publicテつGenericIComparer(Stringテつpropname)
テつテつテつテつテつテつテつテつテつ:テつ
this(propname,テつ false)テつ{
テつテつテつテつテつテつ}
テつ
テつテつテつテつテつテつ
publicテつGenericIComparer(Stringテつpropname,テつ boolテつmReversed)テつ:
テつテつテつテつテつテつテつテつテつ
this(typeof(T).GetProperty(propname).GetGetMethod(),テつmReversed)テつ{テつ}
テつ
テつテつテつテつテつテつ
publicテつ boolテつReversedテつ{
テつテつテつテつテつテつテつテつテつ
getテつ{テつ returnテつmReversed;テつ}
テつテつテつテつテつテつテつテつテつ
setテつ{テつmReversedテつ=テつ value;テつ}
テつテつテつテつテつテつ}
テつテつテつテつテつテつ
privateテつ BooleanテつmReversedテつ=テつ false;
テつ
テつテつテつテつテつテつ#regionテつIComparer<T>テつMembers
テつ
テつテつテつテつテつテつ
publicテつ intテつCompare(Tテつx,テつTテつy)テつ{
テつテつテつテつテつテつテつテつテつ
IComparableテつobj1テつ=テつ(IComparable)methodInfo.Invoke(x,テつ null);
テつテつテつテつテつテつテつテつテつ
IComparableテつobj2テつ=テつ(IComparable)methodInfo.Invoke(y,テつ null);
テつ
テつテつテつテつテつテつテつテつテつ
Int32テつresultテつ=テつ(obj1.CompareTo(obj2));
テつテつテつテつテつテつテつテつテつ
returnテつmReversedテつ?テつ-resultテつ:テつresult;
テつテつテつテつテつテつ}
テつ
テつテつテつテつテつテつ#endregion
テつテつテつ}

This version support a property called Reversed that is used to compare in reverse order. As you can see this class grab the methodInfo related to the getter part of the property in the constructor, to reduce calls to GetProperty() function. As you can see this class has an internal constructor that accepts a MethodBase passed from the caller, this is necessary to go a step further into the optimization, a factory class that optimize the creation of GenericIComparer objects.

テつテつテつ publicテつ staticテつ classテつ GenericComparerFactoryテつ{
テつ
テつテつテつテつテつテつ
privateテつ readonlyテつ staticテつ Dictionary<Type,テつ Dictionary<String,テつ RuntimeMethodHandle>>テつcomparersテつ=
テつテつテつテつテつテつテつテつテつ
newテつ Dictionary<Type,テつ Dictionary<string,テつ RuntimeMethodHandle>>();
テつ
テつテつテつテつテつテつ
publicテつ staticテつ GenericIComparer<T>テつGetComparer<T>(stringテつpropertyName,テつ boolテつreversed)テつ{
テつテつテつテつテつテつテつテつテつ
//Checkテつifテつtheテつtypeテつarrayテつforテつthisテつcomparerテつwasテつcreated.
テつテつテつテつテつテつテつテつテつ
ifテつ(!comparers.ContainsKey(typeof(T)))
テつテつテつテつテつテつテつテつテつテつテつテつcomparers.Add(
typeof(T),テつ newテつ Dictionary<string,テつ RuntimeMethodHandle>());
テつテつテつテつテつテつテつテつテつ
ifテつ(!comparers[typeof(T)].ContainsKey(propertyName))
テつテつテつテつテつテつテつテつテつテつテつテつcomparers[
typeof(T)].Add(
テつテつテつテつテつテつテつテつテつテつテつテつテつテつテつpropertyName,テつ
テつテつテつテつテつテつテつテつテつテつテつテつテつテつテつ
typeof(T).GetProperty(propertyName).GetGetMethod().MethodHandle);
テつテつテつテつテつテつテつテつテつ
returnテつ(GenericIComparer<T>)テつ newテつ GenericIComparer<T>(テつ
テつテつテつテつテつテつテつテつテつテつテつテつ
MethodInfo.GetMethodFromHandle(comparers[typeof(T)][propertyName]),テつreversed);
テつテつテつテつテつテつ}
テつ
テつテつテつテつテつテつ
publicテつ staticテつ GenericIComparer<T>テつGetComparer<T>(stringテつpropertyName)テつ{
テつテつテつテつテつテつテつテつテつ
returnテつGetComparer<T>(propertyName);
テつ
テつテつテつテつテつテつ}
テつテつテつ}

This class hold a dictionary of propertyName, RuntimeMethodHandle objects for each type. The RuntimeMethodHandle is a further optimization to save memory used to store MethodInfo objects. A MethodInfo object is a big object to store into memory, so it has a readonly property called MethodHandle that will return a IntPtr that uniquely identify that method info. The GenericComparerFactory can reduce the use of the memory, storing into the dictionary a IntPtr object, and recreating the MethodInfo object with the GetMethodFromHandle() function of the MethodInfo object only when it is necessary. With these optimization the GenericIComparer has a small memory footprint and maximum performance.

Alk.

テつ

C# anonymous delegates and template pattern

Yesterday I blogged on a slightly modified version of Ayende code posted here, this makes me reflect on template pattern of the GOF. Template pattern is one of the most useful pattern, and is used when you have a common block of code that is to be repeated in may part with a little customization. In the GOF the intent of the pattern is

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

The original description of the pattern explicitly states that the implementation is made by a template class (usually abstract) and then a series of subclasses, each for a different variation of the algorithm that is to be implemented. C# anonymous delegates are a great way to implement a template pattern even with a static class, without the need to use subclasses or inheritance. The post from Ayende is a great example of this. In his code Ayende creates a base method that accepts a delegate with all the common infrastructure to execute ad Ado.NET DbCommand. In the base static function he creates connection, starts a transaction and creates a command that will be attached to an open connection, then he calls the delegates passed as an argument. With anonymous delegate the caller is able to specify a block of code that logically will be substituted into the inner part of the Template static method. This kind of implementation can also be done in C++ with function pointer, but is definitively not so readable as counterpart in C#.

Alk.

The old plain C language

A friend of mine is taking a basic course in computer programming, and actually he is studying the basic of C language. Yesterday he told me that he must do a very simple exercise that will print on screen a triangle like this
XXXXXXXXXX
XXXXXXXXX
XXXXXXXX

And so on. He asked me if I could review his solution before he give his program to the teacher, because he is moving from the old house to a new house and actually he do not have access to a computer to try his solution. This morning I decided to refresh my knowledge of C solving this simple exercise, I must admit that I love C/C++テ「竄ャツヲ.I cannot explain but they are really fascinating languages (I love assembly language too)

#includeテつ “stdio.h”
#includeテつ “memory.h”
テつ
#defineテつNUM_OF_CHARSテつ10
テつ
intテつmain()テつ{
テつテつテつ
charテつstr[NUM_OF_CHARSテつ+テつ1];
テつテつテつ
intテつI;
テつテつテつmemset(str,テつ
‘X’,テつNUM_OF_CHARS);
テつテつテつ
forテつ(Iテつ=テつNUM_OF_CHARS;テつIテつ>テつ0;テつ–I)テつ{
テつテつテつテつテつテつstr[I]テつ=テつ
‘\0′;テつ
テつテつテつテつテつテつprintf(
“%s\n”,テつstr);
テつテつテつ}テつ
}

The ability to manage memory of a string is one of the feature that I missed most when I program in C#.

Alk.