Archives for : generics

Tiptoe Through the Tulips … LINQeses…es

As most can attest when launching into the world of WPF you have to jump in and hope you can figure out how to swim before you drown.  It has a huge learning curve but the end results are usually pretty amazing.

LINQ, on the other hand, you can slowly dip a toe in, see how tepid the water is, and then slowly immerse your whole body sliding into the warm 98 degree water.  Over the course of 7 months now I have been slowing dipping into the water called LINQ and wanted to give you a few examples where I found it particularly useful.  Unlike a cruel father I will not throw you into the water and hope you can swim but want to slowly lead you into the fold.

So what the hell is LINQ?  Well, it stands for Language INtegrated Query.  It is a way to query lists in code.  Really that’s it.  You’re f-in me Brian, aren’t you?  Yes, yes I am.  That is the fundamental idea behind LINQ but it can do so much more.

I suppose I should start with the var keyword.  You VB fans will cheer at this.  var is a variable declaration where the type of the variable is implicit in the constructor of the item being created.  This is similar to the Dim except that we are still statically typed here.  In .Net 3.5 the var keyword can be used anywhere you are defining a variable that the type can be implied.

Good Examples:

var myInt = 3;
var myDouble = 2.2;
var files = new List<FileInfo>();

Bad Examples:

var myDouble = 3;//not a double and myDouble will actually be an int
var myString = null;//type cannot be implied, will result in compile error

The easiest use for LINQ is in sorting.  No more needing to define an IComparable, just define your sort in an orderby clause.  LINQ has some similarities to writing SQL except that in order to facilitate compilation and intelli-sense the order of the query is a bit different.

Take this code for example:

//START CODE
var files = new List<FileInfo>();
var ArchiveDirectory = "C:Archive";
var archivedFiles = Directory.GetFiles(ArchiveDirectory);//will be of type string []
foreach (var filePath in archivedFiles)
{
    var fi = new FileInfo(filePath);
    files.Add(fi);
}
//now sort the file list based on last write time
var sortedFiles = from file in files orderby file.LastWriteTime descending select file;
//END CODE

Now, up until that last line it is standard C#.  The last line appears to be some sort of odd jacked-up sql.  If we break it down, however, you will see the power.

from file in files

basically for each file in our files list

orderby file.LastWriteTime

LastWriteTime is a property on FileInfo.  files is a list of FileInfo, therefore each file is a FileInfo object.  Intelli-sense is fully supported here so when you type in file and put the dot it shows you all the properties on file as if it were a standardly declared FileInfo.

descending

Like a standard DESC to an orderby clause.  Like sql it implicitly orders by ASC so if you want descending you have to add it.

select file

return the file that applies to the orderby clause.  The may seem a bit redundant and I would agree but it is still needed.

See?  Pretty simple.  No need to write an IComparable just order the list by the LastWriteTime.

So let’s take this a step further.

I have an example where I have three different tables all of which have the property “Name”.  I need to populate three different combo boxes with the values from each of the different tables.  Now I could write a whole bunch of code to do each table values and combo boxes separately but, well, nah!

Here we’re going to go a bit extreme.  Use a bit of LINQ, throw in some Generics and finally whip it all together with some Reflection.

Start with getting each list and ordering it by name

//START CODE
var sortedTypes = from type in new TypeService().GetAll() orderby type.Name select type;
var sortedFreqs = from freq in new FrequencyService().GetAll() orderby freq.Name select freq;
var sortedEvents = from event in new EventService().GetAll() orderby event.Name select event;
//END CODE

Well, that should be pretty straight forward now.  We can see the GetAll method of each service returns all the values from a table in the form of a list.  The we use the orderby clause in LINQ to sort it for us by the name.

Now let’s populate the combo boxes in the form:

//START CODE
PopulateComboBox<Type>(sortedTypes, cboType);
PopulateComboBox<Frequency>(sortedFreqs, cboFrequency);
PopulateComboBox<Event>(sortedEvents, cboEvent);
//END CODE

And thats all there is.  Pretty simple, huh?
Oh, you want to see what the hell PopulateComboBox does.  Fine, be that way.

//START CODE
private void PopulateComboBox<T>(System.Linq.IOrderedEnumerable<T> List, ComboBox Box)
{
    foreach (T val in List)
    {
        ComboBoxItem cbi = new ComboBoxItem
            {
                Content = FindReflectedProperty(val, "Name"),
                Tag = val
            };
        Box.Items.Add(cbi);
    }
}
//END CODE

As you can see we can’t take a var on the first value of the parameter since it’s type cannot be inferred.  As it would happen using the orderby clause in a LINQ query returns a list with the interface System.Linq.IOrderedEnumerable.  We use the good ole’ generics typeparam when calling the method so at runtime the code knows the type of T.  Additionally you can see that when creating the ComboBoxItem we use the new feature in 3.5 of setting properties on the objects when creating the object (really this happens right after the constructor is called).  The final bit to this is FindReflectedProperty.

//START CODE
public static object FindReflectedProperty(object Instance, string PropName)
{
    if (Instance == null)
        return null;
    foreach (PropertyInfo pi in Instance.GetType().GetProperties())
    {
        if (pi.Name == PropName)
            return pi.GetValue(Instance, null);
    }
    return null;
}
//END CODE

Getting the PropertyInfo on the instance passed in we are able to get the value of the property based on the property name.  Of course we can turn this method into more LINQ but I’ll leave that to the next in the series where we’ll dip our whole foot in, which should excite all you foot appreciators (or fetishes or whatever).  If you want to read ahead google LINQ Lambda.

And now your toe is wet, assuming you got this far.

Later ‘yall,
Brian

Generics, Params, IEnumerables (well, yield), Oh my!

Hello all,

Well, what once was a simple weekly email about cool stuff I ran across while working in DotNet has suddenly become very complicated. I spoke briefly with the devs on Generics the other day and wanted to throw together a more concrete example of using them. In the attached solution you will find a quite thorough example of using generics in a BinaryTree class I wrote. It’s important to remember that T is simply a type and tells your code what type to expect. Please ignore the bit of kludge in the AddNode method between IComparable and IComparable<T>. This was meant to be thrown together and I didn’t want to spend too much time on it.

In case you missed it above, here is the attached solution

In looking at the code for Form1 you can see the generics in action in the button1_Click event. The power of generics really comes through for compile time issues with not having to worry about casting. Here we create trees for int, string and a class I added called City. Since City implements IComparable we can use it for the tree.

By declaring,

BinaryTree<int> intTree = new BinaryTree<int>();

we know we have a btree that has ints and without casting we can do with
those ints as we please. Then any methods in the btree knows that the
value is an int.

This btree example, however, has two other things that are pretty cool.
The first is the use of an add method that takes
params T[] Items

I love using params as it allows for variable length parameters on
methods. Um, well, not a lot to say on params, just that they’re cool.

The other cool thing is the usage of yield in the ScanInOrder method.
yield basically allows you to return from a method when iterating over a
list of items where the code will remember where you were at so that you
can return back to that position. The cool thing about using yield is
that, as shown in the sample, you can use yield multiple times in the
same method. As we all know for an InOrder traversal of a binary tree
we basically move down the left side of the tree, give our value and
then start working on the right side of the tree (well, y’all know its a
bit more then that but I don’t think I have to explain it). Here in the
ScanInOrder method of the BinaryTree class it recursively calls
ScanInOrder on the left nodes of the tree items iterating in a foreach
loop yielding each of the results. Then it returns it’s own result and
finally recursively iterates in a foreach loop over the nodes on the
right side of the tree yielding each of those results.

In the morning my son Edison and I watch Curious George together on the
couch. Right before the cartoon starts KUAT does this cutesy animation
with a song in the back ground that says, “Learn something new
everyday. You learn a lot that way.” Hopefully I’ve helped with that
goal, 🙂

Brian