still travel more than I’d like, although the toll has decreased by at least 50 percent over the past few years. I used to read while traveling because I never really seem to have time to read for pleasure at home. A new technology-based pastime has taken its place, however?I now seem to spend most of my spare time on the road catching up on episodes of TV shows that I missed in real time, or wasn’t “allowed” to watch at home. (I don’t tend to watch movies on the road because I rarely have two hours free at a time. It’s far easier to catch one 42-minute TV show?an hour-long show with the commercials removed.)
Thanks to the dual technologies of iTunes and DVD ripping, I don’t even carry DVDs with me. I download from iTunes and peer at the little 2″ screen, when I’m too lazy to get out my laptop. I also have found the (probably slightly illegal in the US) program AnyDVD works great for ripping the contents of DVDs to my hard drive, so I can store entire seasons of TV shows for later perusal.
And what do I watch? Any self-respecting sci-fi devotee probably has already seen (or should see, if you haven’t) the entire first three seasons of the new Battlestar Gallactica. It’s got everything: interesting stories, robots, occasional implied sex (nothing too graphic to watch in front of your mother), and lots and lots of intrigue. It’s occasionally depressing, occasionally shocking. Every time I tell anyone I’m watching this, they laugh, thinking I’m referring to the cheesy 70’s series by the same name, from which the current invocation was inspired. Don’t laugh: if you haven’t treated yourself to this show, and you like sci-fi, rush over to the iTunes store and check it out.
I watch lots of other series. The entire Oz series from HBO (didn’t watch that one on the plane, however. If you’ve seen it, you know why.) The entire Deadwood series. All of Alias (which got seriously bad in its last two seasons). And, to be honest, my one guilty pleasure: I love Gilmore Girls. Yes, I know. It’s a show for women. I’m not a woman. But I love it. It’s got snappy writing, clever dialog, and excellent acting (for the most part). I don’t remember laughing out loud at any TV show as much as I do with this one, and I love the obscure cultural and intellectual references. It’s off the air now, but it ran for six or seven years. It is/was lots of fun: check it out if you’re so inclined, and have 42 minutes to kill on a plane sometime.
When not watching TV shows, I’ve spent a lot of time over the past few months digging into new features in Visual Studio 2008. (With coauthor Robert Green, I’ve been preparing a new course for AppDev: Exploring Visual Studio 2008. With luck, the course should be available just a few weeks after this article appears in print.) We split the new features between us, and luckily, I ended up with a feature to cover that I’ve found delightful, from the moment I first started playing with it.
That feature, of course, is LINQ (Language Integrated Query). Maybe it’s because I started my programming career at Ashton-Tate, working with dBASE III (which had a querying language that was similar in intent to LINQ), or because this is just a really cool feature, but the entire week I spent learning LINQ, I said “This is the coolest feature I’ve ever seen!” more times than I can count.
For those who haven’t looked into LINQ yet, it’s really a language feature in both Visual Basic and C# that allows you to construct queries over just about any type of data, including your own collections of objects. Because it’s a language feature, LINQ provides full IntelliSense support. Combined with new language features such as implicitly typed variables and lambda expressions (see the last instance of this column for more information), LINQ makes it quick and easy to retrieve an enumerable list of items matching any criterion you care to specify.
LINQ, in theory, can retrieve data from any data source. The .NET Framework 3.5 includes LINQ provides for SQL and XML data, as well as the ability to use LINQ over just about any collection of objects. I won’t focus on using LINQ over data here?you’ll find plenty of articles covering this important topic. My guilty pleasure is looking for any excuse to use LINQ over collections of objects. I love to reduce code to its simplest form, and taking advantage of LINQ can help remove a lot of bulk from your code.
As an example, imagine that you want to display a list of running Windows services in a CheckedListBox control. After setting a reference to the System.ServiceProcess assembly, you could call the ServiceProcess.GetServices method, then loop through all the services, checking the state of each. Finally, you could add each running service’s name as an item in the CheckedListBox control. Or, in Visual Studio 2008, you could write that code in a LINQ query, like this:
[Visual Basic] Dim services = _ From s In ServiceController.GetServices() _ Where s.Status = _ ServiceControllerStatus.Running _ Select s.DisplayName CheckedListBox1.DataSource = services.ToList() [C#] var services = from s in ServiceController.GetServices() where s.Status == ServiceControllerStatus.Running select s.DisplayName; checkedListBox1.DataSource = services.ToList();
The first thing to note is that you don’t need to supply a type for the services variable (in C#, use the var keyword to indicate that you want type inference)?the compiler infers the type, based on the query expression. (If you like, set a breakpoint on this line of code, and at runtime, hover over the services variable to determine its type.) The query takes the form of a from?where?select statement, and allows you to specify the subset of “rows” and “columns” that you’d like to retrieve from the original set of data?the collection of ServiceProcess objects returned by the call to the GetServices method. You can bind the results of the returned query to the CheckedListBox by converting it to a list, using the ToList method. Obviously, I can’t describe the full syntax for LINQ queries here, but you’ll find plenty of information about LINQ on Microsoft’s site.
As another example of “looking for reasons to use LINQ”, I often find myself needing to iterate through all the controls on a form in order to find all the controls of a particular type. For example, I might want to make some change to a particular property of all the Button controls on a form, or all the TextBox controls. I’ve long been looking for a way to say to .NET, “Hand me a collection of all the buttons on the form. Don’t make me loop through all the controls to find it.” As you might guess, LINQ can do this for you. By applying extension methods to the query, you can filter the query results in a number of different ways. For this example, you can use the OfType function, which restricts the results based on the type of each element. To try it out, you could add code like this to the Click event of a button on a form:
[Visual Basic] Dim buttons = _ (From c As Control In Me.Controls). _ OfType(Of Button)() For Each button In buttons Debug.Print(button.Name) Next c [C#] var buttons = (from Control c in this.Controls select c).OfType
In this case, the Buttons collection contains a collection of (as you guessed) just the controls of type Button on the form. The OfType function is a generic function?you supply the type of its parameter.
There are lots and lots of other uses for LINQ outside of working with data. Recently, I needed to determine if an item already existed in a Word 2007 Content Control’s drop-down list. The control itself doesn’t provide a Contains method, and the alternative was to loop through all the items myself. Using LINQ, I wrote a query which used the Any extension function to determine if any item in the list matched the WHERE clauses I specified in the LINQ query. Does it run faster? I don’t know. But I got a lot of pleasure out of using LINQ to solve it. It’s not quite the same sort of guilty pleasure I get from watching TV shows when I ought to be working, but it’s really a lot of fun. Take the time to learn more about LINQ?perhaps you’ll find the same sort of programming pleasure.
|Editor’s Note: This article was first published in the November/December 2007 issue of CoDe Magazine, and is reprinted here by permission.|