Tuesday, September 12, 2006

New Blog

Blogging is getting better. I have been less than prolific in my blogging, partly because I have almost no time and partly because it just wasn't much fun. That last part seems to be changing with newer tools that make things easier and quicker. I have decided to try other blogware (you can see it here) to take advantage of new features and technology. I'll see how I like it after using it for a while.

Tuesday, August 01, 2006

Another Simple Thing

Sometimes I can get a little long-winded when naming variables or methods. Combine that with a secret desire to write a complete program with one line of code and you can imagine what my code can look like if I don’t exercise a little constraint. With that in mind, I came across this little trick to add vertical guidelines in my editor window. They serve as a reminder that my lines shouldn’t get too long. I have seen this trick before, and actually used it at one time, but forgot about it until recently. Here is what it looks like. Notice the vertical red lines in the editor window.



Ok, how do we get there from here? Crank up Regedit.exe and get ready for some registry surgery (insert the usual warnings about the possible dire consequences of registry editing, etc. here).

Go to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\<your version number (7.1, 8.0, etc.)>\Text Editor and add a new string named “Guides” with the following value: RGB(r,g,b) gl1 gl2 … where r, g, and b are the values (0 .. 255) of the color you want for your guide lines. gl1, gl2, etc. are the column number where you want your guide lines to appear. My guidelines are light red and are located at columns 80 and 110. My registry entry is shown below.



Enjoy, and keep those lines of code short enough to be readable.

It’s the Simple Things

You have to love the simple things that save time and make your life easier. Years ago, back in the days of DOS, I used an editor named Brief. Brief was published by a company named UnderWare and was later acquired by Borland. Borland still has Brief emulation in their editors and so do other publishers. One of the things I liked about Brief and missed in the Visual Studio IDE editor is the ability to select columns of text. It’s the little things I miss when they aren’t available.

One day while editing some code in Visual Studio I accidently selected columns of text. I didn’t know what I had done to cause the column selection but set out on a search for the magic keystroke combination that would duplicate my fat-fingering and bring column selection home to me. After a little trial and error, I discovered that like holding down the shift key while moving the cursor to select rows of text, if I add the Alt key to that combination I can select columns. Interestingly, you have to use Alt-Shift with the arrow keys to select columns with the keyboard, but just Alt will do if you select columns by holding down the left mouse button and dragging the mouse. Don’t ask me why it works like that; it does and I’m loving it.

Friday, July 14, 2006

Creating a Strongly Typed Heterogeneous Collection in .NET 2.0.

I found a solution to an interesting problem while developing an application for a state licensing board. I was using generics for strongly-typed collections of objects, but had a need to have collections of several types of objects that are historical events for a person. In this case, as a person goes through the process of becoming licensed, applications are required for exams, different exams must be taken and passed, and other requirements must be met before licensing can be completed. The historical events don’t end there though. Continuing education requirements must be maintained, complaints might be filed against the licensee, the license may become inactive and later reinstated, or a number of other events could occur. I wanted to be able to maintain a history for each person from first application through licensing and beyond. My first thought was to just maintain collections for each type of historical event. It soon became obvious I would have many collections to manage, so another solution seemed necessary.

After thinking about several approaches, I decided to make a base class named HistoryItem and all of the historical events now derive from it. If you are thinking these items are not related you are partially correct. A license is not a complaint and a complaint is not a license, so there isn’t an “is-a” relationship. A license doesn’t have a complaint and a complaint doesn’t have a license, so there isn’t a “has-a” relationship either. The same can be said about the other historical items and events. Normally we would say the items are not at all related. But, they are historical items or events for a particular person. In other words, they are related because we want to treat them the same way, as historical items. With this approach all the history can be stored in a single collection which will be much easier to manage.

Feeling proud of myself for solving this problem, I turned my attention to manipulating the collections and ran into the reason we usually don’t store different kinds of things in the same collection. How could I compare two items in the collection when they could be different types? I could see the algorithm starting to take shape. If the first item is this type and the second item is that type do something, but if the first item is that type and the second is this type, then do something else, but if they are both the same type then compare some properties to see if they are equal or not. Well, the algorithm is as ugly as that description. Another solution seemed necessary.

I decided comparers would be a big help, so I developed a set of classes that implemented the IComparer interface. If you aren’t familiar with that interface, it has one method named Compare. Compare takes two arguments and since I was using generic collections I wanted strongly typed comparers. Both arguments are HistoryItems. Now I can compare items in my collection, and search for a particular item I might find interesting. But wait, how do I know which comparer to use? I could see the algorithm taking shape. If I’m interested in this type use this comparer, but if I’m interested in that type use that comparer. Once again I was faced with an ugly algorithm and another solution seemed necessary.

What I really wanted was some mechanism that could give me the comparer I needed to use. Fortunately, that is what a factory does. But, a factory needs some information so it can make a decision about what kind of thing to create. I decided to hand my ComparerFactory the HistoryItem currently of interest and ask the factory to provide a comparer I can use with that item. I could see the factory algorithm starting to take shape. If I get this type then create this comparer, but if I get that type then create that comparer, or if I get the other type then create the other comparer. That sounded like another ugly algorithm. It could get even uglier if several new types of items and comparers were developed, so another solution seemed necessary.

If my factory could create any type without knowing anything about the type it was creating all my problems would be solved. I decided my solution should not depend on the type of the item I need to compare, but my item should be able to tell the factory what type of comparer to create. I decided to create a custom attribute that could decorate my items and the factory could use reflection to learn what type of comparer to create. Here is my attribute and how to apply it to a class.


[AttributeUsage(AttributeTargets.Class,
AllowMultiple = false, Inherited = false)]

public class CompatibleComparerAttribute : System.Attribute
{
private string _comparerName;

public string ComparerName
{
get { return _comparerName; }
}

public CompatibleComparerAttribute(string comparerName)
{
_comparerName = comparerName;
}
}


Now apply it to a class.

[CompatibleComparer(“ApplicationComparer”)]
public class Application : HistoryItem
{
. . .
}

Now, my factory knows what type of comparer to create. I can see the algorithm starting to take shape. If I need to create a “ApplicationComparer” then create an instance of ApplicationComparer, but if I need to create a “ThisComparer”, then create an instance of ThisComparer, or if I need to create a “ThatComparer” then create an instance of ThatComparer. My algorithm is as ugly as ever and another solution seems necessary.

The Solution – Putting It All Together

The System.Runtime.Remoting namespace contains a nifty little class named Activator. If you haven’t used it before check it out, it’s very useful. It can create an instance of a class if it knows its full namespace and class name. So, I just need to pass the Activator “FullNameSpace.ClassName” and it will create an instance for me. Putting it all together, I am using a strongly-typed generic collection so I can treat all my HistoryItem instances the same. Each class derived from HistoryItem is decorated with my custom attribute that contains the full namespace and class name for the comparer to use. My factory can use reflection to discover what to create with the Activator. Now, my code looks similar to this:

History history = new History();
. . .
HistoryItem item = new License();
History.Add(item);
. . .
IComparer<HistoryItem> comparer = ComparerFactory.CreateComparer(item);
int index = history.IndexOf(item, comparer);

The factory code itself is very short; this is the only method.

public static IComparer<HistoryItem> CreateComparer(HistoryItem item)
{
object[] attrs = item.GetType().GetCustomAttributes(

typeof(CompatibleComparerAttribute), false);

if (attrs.Length == 0)
{
return null;
}
CompatibleComparerAttribute attr =
attrs[0] as CompatibleComparerAttribute;

ObjectHandle objHandle =
Activator.CreateInstance(null, attr.ComparerName);

return objHandle.Unwrap() as IComparer<HistoryItem>;
}


Now my code is not ugly, and can handle new HistoryItems and comparers in the future. I’m happy and life is good. The .NET library came through with a solution that is simple and can be easily maintained.

Thursday, June 15, 2006

Pro .NET 2.0 Code and Design Standards in C#

Mark Horner takes on the ambitious project of telling us how to standardize code, design, and patterns in “Pro .NET 2.0 Code and Design Standards in C#” published by Apress.  A what, where, why and how format for each topic promised the reasoning and justification for the standard practices.  I had high expectations for a clear explanation of a proposed standard for designing and developing applications in C#.  This book misses the mark and left me wondering what standard was being proposed.

As I read through the book, I kept wondering why the material I had just read was included in the book.  For example, in a book about C# standards the author discusses Visual Basic naming conventions, and even demonstrates the use of a leading underscore for a variable name with Visual Basic code.  The author makes confusing claims such as “…there is always an option to accept a .NET standard, which rules against using case sensitivity (e.g. in C# language).”  The syntax of basic language structures is covered, such as an if statement, including the optional else clause.

The what, where, why and how format of each topic is followed by an acknowledgement of the practice.  Apparently believing the first acknowledgement isn’t enough, a List of Standards is included in the back of the book where the acknowledgements are repeated.

The purpose of the book seems to be mentioning as many topics as possible, whether or not they have anything to do with standards.  For instance, the author felt the need to include the first 128 ASCII characters and parentheses in the glossary but not tell you their purpose.  The entire entry for parentheses is
()     Parentheses.

Compare that to the much more enlightening
‘     Single quote – not a comment (“//” or “/*…*/”).

The weight given topics seems strange as well, with the if statement getting about the same coverage as service oriented architecture, about two pages each.  Based on the title, I expected to see a standard developed.  What a surprise.  At the end of the day what we are left with is not a standard at all, but just acknowledgements that various things exist.  

Maybe I’ve just had my expectations set too high by the excellent “Framework Design Guidelines” by Krzysztof Cwalina and Brad Abrams, but Horner’s book is a big disappointment.  Save your money.