Wednesday, December 07, 2005

SoapSerializer and Generics Don't Mix

After a bunch of monotonous code changes the previously V1.1 application now compiles successfully under V2.0 of .NET with generics in used for all domain model aggregation relationships. One of the first problems arose at runtime was the following exception:

“Soap Serializer does not support serializing Generic Types”

A Soap serializer was chosen originally since it was an (arguably) human readable format and worked with any serializable classes without much effort. Being a lazy programmer I chose the Soap serializer route rather than the XmlSerializer because of the extra effort needed for non public members and more complex classes. The solution to the problem was just to use an ArrayList for the property in question, which fortunately didn’t have too many flow on effects. Still its a shame not to have both a binary and a text based serialization format that serializer/deserialize an arbitrary Serializable class including support for generics.

Monday, December 05, 2005

Generic List Covariance

I’m currently moving an existing .NET Framework V1.1 application to V2.0 and changing the domain model to use generics for any collections and lists. A common theme that keeps popping up during the change over is the lack of generic list covariance. In the following contrived example the Person class is a specialization of the Party class. In the V1.1 application version, an IList containing solely Person instances can be passed to any method that takes an IList and treats the items in the list as Party instances. Once a changeover to use the generic collections functionality is performed, you can’t just pass an IList<Person> instance to a method that takes an IList<Party>. The compiler will only accept passing IList<Party> instances, even though a Person is a Party.

class Party {…}

class Person : Party {…}

static void Main( string [] args )
{
    IList<Person> people = new List<Person>();
    people.Add( new Person( "Fred" ) );
    people.Add( new Person( "Wilma" ) );
    people.Add( new Person( "Barney" ) );

    PrintNames( people );
}

The following definition of PrintNames causes compilation errors since passing an IList<Person> to the method isn’t supported:

static void PrintNames( IList<Party> parties )
{
    foreach ( Party party in parties )
        Console.WriteLine( party.Name );
}

The easiest approach to handle the lack of covariance tends to end up with more use of generics in the source code than I originally expected. The generic version of the method is able to take any IList<T> where T is derived from Party. The compiler makes life easier by accepting PrintNames( people ); as a program statement where PrintNames<Person>( people ); would be the more verbose equivalent. Here’s the generic version of the PrintNames method:

static void PrintNames<T>( IList<T> parties )
    where T : Party
{
    foreach ( Party party in parties )
        Console.WriteLine( party.Name );
}

It reminded me of coding in C++ with the const functionality in terms of coding change effects. The use of generics in the code starts a sort of domino effect of code changes, similar to the flow-on effect of const changes in C++ programs. The short term reason for doing the generic list changes is to be able to create class diagrams of the domain model that shows the aggregation relationships between classes. I’m looking forward to getting these generic code changes over and done with in the app and getting onto less monotonous work.
 

Sunday, December 04, 2005

Dell 2405FPW

I recently splurged and purchased a Dell 2405FPW 23 inch monitor. The (possibly spurious) justification was that it would improve my development productivity by having more real estate. Maybe the real justification was subliminal and relates to all modern movies/TV shows for the last 3 years or so showing all desktops having large thin flat panel monitors all over the place. The existing monitor was a 17” run at 1280x1024. Coming out of the box, the 23” flat panel it didn’t actually look that big. Once it was up an running on the desk displaying the windows desktop, it looked huge. This probably due to the bulk of the CRT hardware screwing up my perceptions of size.

The only real problem I had was that it is way too bright. All the controls are wound back to the minimums for the monitor, yet it still was searing my eyes when the monitor was displaying programs with mostly white backgrounds. I eventually found a setting on the ATI catalyst software to wind back the brightness and contrast to be more comfortable. The controls are under the color properties in the graphic settings. Control “all channels” and then adjust the brightness and contrast to suit.

The multiple inputs were handy this week to test a laptop that was going to be used in a presentation scenario. The Dell monitor acted as the equivalent of the LCD projector to be used at the actual presentation. The main PC was hooked up via a DVI connection. The laptop then had its external monitor plug connected to the standard D-SUB connector. I could easily then switch between the inputs using the buttons on the front of the Dell monitor. This set up help identify that a video play scenario worked on the laptop screen, but ended up as a blank space on the external monitor. The hardware acceleration had to be wound back on the laptop to appear on the external monitor. Identifying this in the office, just made the presentation setup less stressful than it would have been.

The extra width in the aspect ratio for the screen takes a bit of getting used to. I’ve ended up putting the Windows task bar on the left of the screen instead of the bottom. The task bar now has enough width to display more of the titles of the apps running and enough height to list a heap of them. Working with Word in two page display mode is quite handy as well. I’m still playing around with the window layout in Visual Studio 2005 to see what works best. HD videos look fantastic – though I’ll rarely use it for full screen video display. All in all, a good purchase.