Often when working with a textbox or some other control, it is necessary to call the Parse() method to do a conversion for our business object property. For example, consider a web form where you are assigning:
1 | person.DateOfBirth = DateTime.Parse(txtDateOfBirth.Text); |
This is all well and good if your field is required and you've already got a UI validation ensuring that the user typed a date into the text box. But what do you do if the field is not required and you'd like to use Nullable for your DateOfBirth property. Rather than littering your code with a bunch of if/then statements or creating methods to do it, the best bet is to create a re-usable class that can do this for you so that you're syntax can look like this:
1 | person.DateOfBirth = NullableParser.ParseNullableDateTime(txtDateOfBirth.Text); |
NullableParser is a static class (a new feature of C# 2.0) that has a ParseXXX() method for each value type.To implement this internally, our method could simply look like this:
1 2 3 4 5 6 7 8 9 10 11 | public static DateTime? ParseNullableDateTime( string s) { if ( string .IsNullOrEmpty(s)) { return null ; } else { return DateTime.Parse(s); } } |
The problem with this is that I have to write a repetitive IF statement for every single method in my static class - the only thing that would be different would be the return DateTime.Parse(s);
line. In order to solve this issue by making the code more concise, we can leverage a delegate with delegate inference (another new C# 2.0 language features) within a generic method (generic method being another C# 2.0 new language feature). First, we might define our delegate:
1 | private delegate T ParseDelegate( string s); |
Next we define the generic method passing the appropriate delegate:
1 2 3 4 5 6 7 8 9 10 11 | private static Nullable<T> ParseNullable<T>( string s, ParseDelegate<T> parse) where T : struct { if ( string .IsNullOrEmpty(s)) { return null ; } else { return parse(s); } } |
With this simple generic method defined, the rest of the class is trivial as now all of the ParseXXX() methods can be rewritten like this (utilizing the appropriate Parse() method for delegate inference):
1 2 3 4 | public static int ? ParseNullableInt( string s) { return ParseNullable< int >(s, int .Parse); } |
Leveraging the new features of C# 2.0 (i.e., nullable types, delegate inference, and generics) can result in code that is more efficient, concise, and easier to maintain.