I suspect that out there in Internet-land I have many as yet unmet kindred spirits. By this I mean programmers that I haven't met that bend and twist what a language can do just for fun. (You know the kind of activity that might cause a normal person to tell you to get a life.) Some people drink wine, some watch Adam Lambert on American Idol (hey his spin on Dilana Smith's spin on Johnny Cash's Ring of Fire is awesome if you like Nine Inch Nails), some fly planes, write poetry, cook, play instruments, take TaeKwonDo lessons with Master Shinn, and some, like me, like to take the language out for a spin and see what she'll do. So, if you are really serious--of the "programming is about solving problems" set or you have lost your inner child on the path of life--then you can skip this blog entry because it suffers from an excess of frivolity.
A month ago a reader responded to an article I wrote on calculating prime numbers--http://www.codeguru.com/columns/vb/article.php/c6575. In essence his first missive can be Cliff-noted as you are an idiot and your algorithm sucks! Of course, if I had wanted to start a digital bar fight, I could have called him a Nazi. Since I am only an Internet white belt I sent back a pleasant: thank you for your feedback and thank you for taking your valuable time to improve on my grossly inferior article. Diffused he wrote back and apologized. The reader indicated that he had been refining the Sieve of Eratosthenes for 40 years--that's 4-0 years--and felt partial to it. (What I wanted to write back is if you can't do a better job than me after 40 years of effort then you are complete idiot as well as a jerk. I didn't. I didn't because I obsess about algorithms in the same way. I work and re-work algorithms dozens, if not hundreds of times. I like doing it. My girlfriend has a name for it that sounds like "asp" and "burger" . My girlfriend means "obsessing", and when I do it take it as intense interest.
One such obsessive algorithm for me is an object state dumper. I write so much code and so many tests that it is intrinsically useful to me to know what state my objects are in. (Hey, I got the idea from Dave Thielen's No Bugs!: Delivering Error-Free Code in C and C++and so did everyone else after Dave.) Consequently I have written (and published) dozens of things on an object's state dumper. (Of course, Microsoft came out with the ObjectDumper and killed my claim to fame.) And, I have re-written the state dumper several times. In this blog I thought I'd try writing a state dumper with LINQ. (I know it took forever to get to the point but writing and coding all day sometimes causes meanderitis.) Listing 1 contains an object state dumper written in LINQ. I hope you have fun with it.
Listing 1: An object state dumper courtesy the lone way around of Dave Thielen and Jeffrey Kenton.
public static void LinqDump<T>(IEnumerable<T> list, TextWriter writer)
{
string mask = "{0} : {1}";
var results = from obj in list
let properties = typeof(T).GetProperties()
from prop in properties
select
prop.GetValue(obj, null) != null ?
string.Format(mask, prop.Name, prop.GetValue(obj, null)) :
string.Format(mask, prop.Name, "unk.");
Array.ForEach(results.ToArray(), s => writer.WriteLine(s));
}
The code essentially uses a nested from to iterate the list of incoming objects and then the properties to return an enumerable collection of strings stating the property name and value. The Array.ForEach sends the results out to whatever TextWriter happens to be (like Console.Out). The first drawback--among several, including esoterrorism--is that the function uses a second pass to send the results to the TextWriter. Listing 2 contains a side-effects version that uses a generic function type to display the results while iterating.
Listing 2: Using side-effects to send the value to the stream while iterating.
public static void LinqDump<T>(IEnumerable<T> list, TextWriter writer)
{
string mask = "{0} : {1}";
Func<string, string> sideEffects = obj =>
{
writer.WriteLine(obj);
return obj;
};
var results = from obj in list
let properties = typeof(T).GetProperties()
from prop in properties
select
prop.GetValue(obj, null) != null ?
sideEffects(string.Format(mask, prop.Name, prop.GetValue(obj, null))) :
sideEffects(string.Format(mask, prop.Name, "unk."));
}
In Listing 2 results is wasted, but you avoid iterating over the data a second time.
OK. Time to fess up. What has any of this to do with Developer Express's controls? Nothing directly. My boss Ray said blog about LINQ because you wrote a book--LINQ Unleashed for C#--and it should be easy for you to whip out some blogs on LINQ, so I wrote about LINQ stuff. It is also worth noting that Developer Express is a great place to work, the people are smart--like Oliver Sturm, Mehul Harry, Mark Miller and others--and I have witnessed first hand how they expend a lot of energy figuring out what would make you guys more productive, do a better job, and have more fun. Since, its after 6PM I thought I would pitch in on the fun factor bit.
If you can improve on the code above--make it smaller, faster, or cooler then respond to the blog. If you are going to the Central Ohio Day of .NET in Columbus on April 18th or TechEd in LA in May then stop by the Developer Express booth and say hello.