Fabrice's weblog

Tools and Source

News

My .NET Toolbox
An error occured. See the script errors signaled by your web browser.
No tools selected yet
.NET tools by SharpToolbox.com

Read sample chapters or buy LINQ in Action now!
Our LINQ book is also available on AMAZON

.NET jobs

Emplois .NET

Tuneo

ASP.NET Hosting transatlantys

Contact

Me

Others

Selected content

Archives

December 2007 - Posts

Hunting down bad try..catch blocks

Way too often developers take the easy solution to use try..catch blocks to silence and ignore exceptions.

There are two things to do when you see this happening:

  1. Explain the developers why it's a bad practice (exceptions are costly and their use should be reserved to exceptional cases), and teach them how to do better (use TryParse, test upfront for known problematic values, etc.)
  2. Hunt down the bad blocks and remove them whenever possible

To spot try..catch blocks with empty catch statements, you can use something simple: Visual Studio's search feature, which allows you to search in files. Of course, you can start by looking for catch{} and catch {} and catch { } and catch {}, but that makes several cases, and doesn't cover the cases where there are line breaks. Luckily, Visual Studio's search support regular expressions, so you can devise one that would match all cases. To get you started, here are some you can use catch.*:b*\n:b*\{:b*\n*:b*\} and catch.*:b*\n:b*\{\} and catch.*:b*\n:b*\{.*\}

I wrote these quickly, so they can be improved. Any expert in regular expression should be able to write a single expression that matches all cases... This could be further improved to include the catch blocks that contain comments such as // ignore exceptions or /* simply ignore this problem */.

ISBN-13 to ISBN-10

If for some reason you need to convert an ISBN-13 to ISBN-10 (one being that Amazon doesn't support ISBN-13 in product affiliate links) then you need not only to remove the first three characters. You also need to recompute the checksum.

Here is a piece of code that I wrote to handle this conversion:

public static String Isbn13to10(String isbn13)
{
  if (String.IsNullOrEmpty(isbn13))
    throw new ArgumentNullException("isbn13");
  isbn13 = isbn13.Replace("-", "").Replace(" ", "");
  if (isbn13.Length != 13)
    throw new ArgumentException("The ISBN doesn't contain 13 characters.", "isbn13");

  String isbn10 = isbn13.Substring(3, 9);
  int checksum = 0;
  int weight = 10;

  foreach (Char c in isbn10)
  {
    checksum += (int)Char.GetNumericValue(c) * weight;
    weight--;
  }

  checksum = 11-(checksum % 11);
  if (checksum == 10)
    isbn10 += "X";
  else if (checksum == 11)
    isbn10 += "0";
  else
    isbn10 += checksum;

  return isbn10;
}


I use this to create the Amazon affiliate links on Clair de Bulle, the famous French comics website of my wife. Yes, it's the holidays season, so I have to work for her ;-)

LINQ in Action samples source code

LINQ in Action won't be available as a paper book before January, but the e-book is already available in preview, and of course .NET 3.5 and Visual Studio 2008 are there. This is why we are now able to publish the complete source code for all the samples included in the book (this includes updated source code for LINQ to Amazon). Feel free to download it even if you don't own the book (yet) and provide feedback in the book's forum.

Enjoy LINQ!


Cross-posted from http://linqinaction.net
Use the power of let in your LINQ queries

Often, when you try to find out how to write the correct LINQ query you need, you end up being confused because it becomes too complex. In such situations, you should remember that the let clause is here to help you.

Let's see is an example from the official LINQ forum.
Someone asked how to query the following XML document:

<cars>
  <car name="Toyota Coupe">
    <profile name="Vendor" value="Toyota"/>
    <profile name="Model" value="Celica"/>
    <profile name="Doors" value="2"/>
    <support name="Racing" value="yes"/>
    <support name="Towing" value="no"/>
  </car>
  <car name="Honda Accord Aerodec">
    <profile name="Vendor" value="Honda"/>
    <profile name="Model" value="Accord"/>
    <profile name="Doors" value="4"/>
    <support name="Racing" value="no"/>
    <support name="Towing" value="yes"/>
  </car>
</cars>

Here is one way to do it:

from car in root.Elements("car")
let profiles =
  from profile in car.Elements("profile")
  select new {
    Name = profile.Attribute("name").Value,
    Value = profile.Attribute("value").Value
  }
let supports =
  from support in car.Elements("support")
  select new {
    Name = support.Attribute("name").Value,
    Value = support.Attribute("value").Value
  }
select new Car {
  Name = car.Attribute("name").Value,
  Vendor = profiles.Single(prof => prof.Name == "Vendor").Value,
  Model = profiles.Single(prof => prof.Name == "Model").Value,
  Doors = int.Parse(profiles.Single(prof => prof.Name == "Doors").Value),
  RacingSupport = supports.Single(sup => sup.Name == "Racing").Value == "yes"
};

It's easier to isolate the "profile" and "support" elements in separate sequences using let clauses, as above. Then the select clause becomes simple to write.

As Luke Hoban explains on his blog: 

With let query clauses, you can introduce a variable into scope and use it in the subsequent query clauses. Similar to local variables in a method body, this gives you a way to avoid evaluating a common expression multiple times by storing it in a variable. This can be very useful even in much simpler queries. Of course, in the query above - let is absolutely critical.

The "query above" he refers to is a ray tracer coded as a big LINQ query full of let clauses!


Cross-posted from http://LinqInAction.net

LINQ in Action forum

Did you know that a forum dedicated to LINQ in Action is available? It was already available from the book's web page at Manning, but we've just added a link to it in the top menu of this site so it can be found more easily. You can use this forum for posting comments about the book and for discussing about LINQ with the authors (Steve, Jim, and I).

We are very happy because we've started to receive positive feedback for LINQ in Action. Let's hope this is just a beginning ;-)

Fabrice


Cross-posted from http://linqinaction.net
Posted: Dec 04 2007, 12:44 AM by Fabrice Marguerie | with no comments
Filed under: ,
More Posts