How will you make it if you never even try?

April 2, 2009

Some more good ideas about parameter validation in C#

Filed under: C# — Tags: , , , , , — charlieflowers @ 6:20 am

As you can tell from several recent posts, I’m very interested in good syntax for parameter validation. The new features in C# 3.0 make so many things possible. I found another excellent post, from John Gilliland. He “amplifies” each plain old argument value into an ArgumentEx<T> instance, and then hangs extension methods such as “NotNull” and “InRange” off of ArgumentEx<T>. He uses an implicit conversion operator to make it easy to treat an ArgumentEx<T> as the plain old argument value.

Very nice, very thorough. Check it out. I’d like to combine elements of his approach with the lambda expression idea that allows you to avoid specifying both the parameter and the parameter name as a string.

Advertisements

Example where calling Extension Methods on null references is useful: Parameter Validation

Filed under: C# — Tags: , , , , , — charlieflowers @ 2:56 am

In a recent post, I pointed out that extension methods can be called on null references. For example, this works perfectly fine:

public static void PrintToConsole(this string self)
{
   if(self != null)
      Console.WriteLine("The string is: " + self);
   else
      Console.WriteLine("The string is NULL.");
}

// Elsewhere in the code
string myString = null;
myString.PrintToConsole();

I said I’d give some examples of where this would actually be useful (not just a gimmick as it might appear on first blush).

One such case is parameter validation. Rick Brewster has come up with a fantastic approach for parameter validation, which lets your code look something like this:

public static void Copy(T[] dst, long dstOffset, T[] src, long srcOffset, long length)
{
    Validate.Begin()
     .IsNotNull(dst, “dst”)
     .IsNotNull(src, “src”)
     .Check()
     .IsPositive(length)
     .IsIndexInRange(dst, dstOffset, “dstOffset”)
     .IsIndexInRange(dst, dstOffset + length, “dstOffset + length”)
     .IsIndexInRange(src, srcOffset, “srcOffset”)
     .IsIndexInRange(src, srcOffset + length, “srcOffset + length”)
     .Check();
  
     // Further code snipped.
}

No doubt that’s beautiful syntax. But one of Rick’s main goals was this: Incur the least possible overhead if the parameters are all correct. In particular, don’t instantiate any additional objects if the parameters are correct.

And the way this is achieved depends on the fact that extension methods can be called on null references. If all the parameters are OK, the Begin() method, the IsNotNull() method, and so on, all return null. However, they still have a return type, and that return type has extension methods on it called “Begin”, “IsNotNull”, “IsPositive” and so forth.

You can learn more about Rick’s approach here and here.

C# Delights: Extension methods can be called on null references (and that’s extremely useful)

Filed under: C# — Tags: , , , — charlieflowers @ 12:42 am

Did you know that C# extension methods can be called on null references?? Yes, they can. For example, the following method …

public static void PrintToConsole(this string self)
{
   if(self != null)
      Console.WriteLine("The string is: " + self);
   else
      Console.WriteLine("The string is NULL.");
}

… can be called as follows:

string someString = null;

someString.PrintToConsole();

The output would be:
The string is NULL.

Is this just a gimmick? You might think so at first blush, but it is actually remarkably useful. I’ll write another post soon giving some examples of when it is useful. Here’s one hint: imagine a case where you don’t want the overhead of instantiating objects unless you’re in an unusual situation. (OK, here’s another hint … what if you want to write code that applies business logic to non-null values, but seamlessly ignores nulls, so that the code doesn’t have to be all cluttered up with null checks).

April 1, 2009

Git on Windows and behind Firewalls

Filed under: C# — Tags: , , , , — charlieflowers @ 9:11 pm

I do .NET development on my Mac, and for source code management I use Git from the Mac Terminal window. But once I’ve developed the code, I have to get it onto the company’s development server, which is a Windows machine behind a firewall. I do this using git on Windows.

There are multiple choices for Git on Windows, but I chose the MSysGit route. I used putty to get around the firewall issues. I also had to set the whitespace setting in the MSysGit repo to match what it is by default on Unix — without that, things still worked but Git would change Windows-typical line endings to Unix line endings, causing a diff to think every single line had changed.

Once I worked through all that, everything worked beautifully (and it has for months now). I code on my machine, push to a GitHub repo, and the pull from GitHub to the Development Server (using MSysGit / Putty).

I culled through 100’s of articles while getting this set up. Here are the hand-picked articles that were the most helpful for me.

C# Delights: You can put Extension Methods onto Enums!

Filed under: C# — Tags: , , , , — charlieflowers @ 8:04 am

Often, you need to associate other information with the members of an Enum. For example, say you have the following enum:

public enum DaysOfWeek : int
{
   Sunday = 1,
   Monday = 2,
   Tuesday = 3,
   Wednesday = 4,
   Thursday = 5,
   Friday = 6,
   Saturday = 7
}

That’s all well and good. But say you need to associate additional information with each enum member. For example, say your legacy database represents the days of the week with the following 2 letter codes: “Sn”, “Mo”, “Te”, “Wn”, “Tr”, “Fi”, “St”. Notice I picked codes that are not intuitive and are not always the first 2 characters. Crazy, but we all know legacy databases can be crazy.

Also, let’s imagine that your company needs to associate a decimal hourly rate with each day, representing the fact that you charge different rates for different days.

C# has a very nice, new way you can do this. Before C# 3.0, the best way I knew of to handle this was to not use an Enum at all. Rather, I would make a class that was much like a singleton, but with more than one instance. It would have a private constructor, so that no other classes outside of it could make instances of it. However, it would expose static properties with the exact set of instances that were allowed (7 in our case, and the properties would be named “Sunday”, “Monday”, etc.). Each instance would have properties for “DatabaseCode”, “Name” and “HourlyRate”. That’s not bad, but the new way is better in many cases.

The new way is this: You can place extension methods onto Enums! So, in our case, we would do the following:

public static class DaysOfWeekExtensions
{
   private static string[] databaseCodes = new string[] { "Sn", "Mo", "Te",
      "Wn", "Tr", "Fi", "St" };

   private static decimal[] rates = new decimal[] { 2.5m, 3.6m, 0m, 1.2m,
      8.8m, 42m, 3.6m };

   public static string DatabaseCode(this DaysOfWeek self)
   {
      int index = (int)self - 1;
      return databaseCodes[index];
   }

   public static decimal HourlyRate(this DaysOfWeek self)
   {
       int index = (int)self - 1;
       return rates[index];
   }
}

And then you’d use it like this:

Console.WriteLine("For Tuesday, the database code is " + 
   DaysOfWeek.Tuesday.DatabaseCode() + " and we charge " +
   DaysOfWeek.Tuesday.HourlyRate() + ".");

Click here for another example.

Elegant, appealing parameter validation syntax in C# 3.0

Filed under: C# — Tags: , , , , — charlieflowers @ 7:21 am

This is a VERY cool trick that leads to much improved syntax for parameter validation in C# 3.0. (Kudos to Jon Fuller).

Often when writing methods, you need to validate that the parameters you’ve received are valid. So you might write some code like this:

public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   if(firstName == null)
      throw new WhateverException("The 'firstName' parameter cannot be null.");

   if(salary < 0)
      throw new WhateverException("The salary must not be negative.");

   // And so on ... you get the idea.
}
&#91;/sourcecode&#93;

When you write that in several places, it is only natural to start thinking about a <em>helper</em> to get rid of some of the duplication. Millions of ways to go about it, and it might look something like this:


public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   ValidationHelper.NotNull("firstName", firstName);
   ValidationHelper.NotNegative("salary", salary);
   // And so on ... you get the idea
}

The thing that sucks about this is that you have to provide the parameter name as a string. You want the error message to say, “The ‘salary’ parameter was severely messed up.” Therefore, it needs “salary” as a string. This is not DRY, because you’ve already designated which parameter you mean. Also, it is not friendly for refactoring.

And C# 3.0 lets you get rid of it!!!! Here’s how:

public void SomeMethod(string firstName, decimal salary, int ageInYears)
{
   ValidationHelper.NotNull( ()=> firstName );
}

The NotNull method is defined as follows:

public static void NotNull(Expression<Func> expr)
{
  if ( ! expr.Compile()().Equals(default(T)))
    return;

  var param = (MemberExpression)expr.Body;
  throw new WhateverException("The parameter '" + param.Member.Name + "' cannot be null.");
}

Notice that the exception message does contain the string “firstName”, but that there IS NO SUCH STRING anywhere in the code! How does this work?

The NotNull method takes an Expression. Because of that, our lambda expression will be turned into an expression tree. That expression tree has one node in it, which is a member expression asking for the value of the “firstName” member. (Why is it a member instead of a parameter? Because C# is generating a closure here and capturing the local variable named “firstName” into the closure. Under the hood, this becomes a class with a member named “firstName”. Our lambda expression is then an expression which asks for the value of that field, which means it is a member expression. And then that expression is turned into an expression tree).

The upshot is that we have no strings, but the helper code can obtain and use the string. Very nice!

You can find more about this here.

Create a free website or blog at WordPress.com.