Posts
208
Comments
1144
Trackbacks
51
TryParse for Nullable Types

In my last post, I discussed creating a static class for Parsing nullable types:

http://geekswithblogs.net/michelotti/archive/2006/01/16/66014.aspx

However, 2.0 also introducing a new TryParse() pattern so that developers would not have to rely on catching exceptions when attempting a Parse() method.  For example:

http://msdn2.microsoft.com/en-us/library/ch92fbc1.aspx

We can incorporate the TryParse pattern into our NullableParser class as well so that our consuming code to look something like this:

DateTime? defaultDate = DateTime.Now;

NullableParser.TryParseNullableDateTime(s, out defaultDate);

person.DateOfBirth = defaultDate;

 

Internally, we can implement this the same way as the ParseXXX() methods by leveraging delegate inference and generics.  First define the delegate:

   1:  private delegate bool TryParseDelegate<T>(string s, out T result);

Now define the private generic method:

 

private static bool TryParseNullable<T>(string s, out Nullable<T> result, TryParseDelegate<T> tryParse) where T : struct

{

  if (string.IsNullOrEmpty(s))

  {

    result = null;

    return true;

  }

  else

  {

    T temp;

    bool success = tryParse(s, out temp);

    result = temp;

    return success;

  }

}

 

Now each public method is trivial to implement:

 

public static bool TryParseNullableDateTime(string s, out DateTime? result)

{

  return TryParseNullable<DateTime>(s, out result, DateTime.TryParse);

}

private delegate bool TryParseDelegate<T>(string s, out T result);

posted on Monday, January 16, 2006 6:35 AM Print
Comments
Gravatar
# re: TryParse for Nullable Types
David Nelson
10/10/2006 8:15 AM
When I try to compile this I get a series of compiler errors the first is: "Constraints are not allowed on non-generic declarations". If I then comment out the constraint I get "The type or namespace name 'T' could not be found". After a series of changes to make this compile I eventually get "'out System.Nullable': static types cannot be used as parameters"

Maybe I'm missing something? Has anyone actually gotten this code to compile?
Gravatar
# re: TryParse for Nullable Types, Corrections
David Nelson
10/10/2006 8:20 AM
Eureka!
I finally got this to work, the following is the new declaration that will allow the code to compile.

public delegate bool TryParseDelegate<T>(string s, out T result);

public static bool TryParseNullable<T>(string s, out Nullable<T> result, TryParseDelegate<T> tryParse) where T : struct
Gravatar
# re: TryParse for Nullable Types
JH
1/15/2007 4:42 PM
Unit testing proved that there was a difference between calling Decimal.TryParse versis the generic TryParseNullable method. Here is the correction that makes it return the same results as if it were being called directly:

public static bool TryParseNullable<T>(string value, out Nullable<T> result, TryParseDelegate<T> tryParse) where T : struct {
if (string.IsNullOrEmpty(value)) {
result = default(T);
return false;
} else {
T temp;
bool success = tryParse(value, out temp);
result = temp;
return success;
}
}
Gravatar
# re: TryParse for Nullable Types
RK
9/25/2007 2:48 PM
Just ran across this and had to comment, I know it's a few months behind.

The point of this utility is not to mimic the .TryParse() method exactly, but to provide some simple methods that will allow nullable types to paly nice with UI.

I can see how one might have a need for utilities to parse data into nullable types, and would want the parsing routines to behave exactly like the built-ins. But then the question is why are you using nullable types in the first place? The TryParse is designed to return the default value if it is passed a null or an invalid string.

My $.02
Gravatar
# re: TryParse for Nullable Types
Toby
10/10/2007 12:51 PM
in response to RK:
nullables are handy in a variety of situations but in my case, I'm using nHibernate and it can map a null data member to a dbnull in the database and this code gives me a clean way of handling the conversion from the UI.
Gravatar
# re: TryParse for Nullable Types
Koenraad De bisschop.
10/10/2008 5:15 AM
Hey Steve,

Nice piece of code. I reworked it a bit to get it even a bit more generic.
public interface ITryParsable<T>
{
bool tryParse(string text, out T result);
}

/// <summary>
/// A parser for nullable types. Will return null when parsing fails.
/// </summary>
/// <typeparam name="T"></typeparam>
///
public class NullableParser<T> where T:struct, ITryParsable<T>
{ /// <summary>
/// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method;
/// </summary>
/// <param name="text">The text.</param>
/// <param name="result">The result.</param>
/// <param name="parser">The parser.</param>
/// <returns></returns>
public static bool GenericNullableParse(string text, out Nullable<T> result,ITryParsable<T> parser)
{
if (string.IsNullOrEmpty(text))
{
result = null;
return true;
}
else
{
T valueToParse;

bool success = parser.tryParse(text, out valueToParse);
if (success)
{
result = valueToParse;
}
else
{
result = null;
}
return success;
}
}

Can be called like this now:

NullableParser<DateTime>.GenericNullableParse(TextBox.Text, out from, DateTime);





Gravatar
# re: TryParse for Nullable Types
jimi
1/20/2009 12:14 PM
here's another option, works better out of the box
Gravatar
# re: TryParse for Nullable Types
paresh khatri
10/4/2009 12:43 PM
I think this one should make even more sense. Why we should always declare a variable to use it as an out parameter

public static Nullable<T> TryParseNullable<T>(string value, TryParseDelegate<T> tryParse) where T : struct
{
Nullable<T> result = default(T);
if (!string.IsNullOrEmpty(value))
{
T temp ;
bool success = tryParse(value, out temp);
result = temp;
}
return result;
}

Now use it as
Nullable<DateTime> d = TryParseNullable(str, DateTime.TryParse);

Or rather pass it directly to a function (Eg. adapter.update(..))
Gravatar
# re: TryParse for Nullable Types
John Dauphine
10/29/2009 9:34 AM
Here is a nullable tryparse that is generic and does not require a delagate http://johndauphine.blogspot.com/2009/10/nullable-tryparse-function-in-c.html

This is how I call it NullableParser<double>.TryParse("10.5", out _NullableDouble );

Gravatar
# re: TryParse for Nullable Types
stamati
11/14/2009 1:22 AM
I like the way you use the interface and overloading for the different types. Up to now I use a list of if statements but this is more elegant.
Gravatar
# re: TryParse for Nullable Types
Eric
8/5/2010 5:45 AM
It is a pity that the initial code is not correct because of missing <T> declaration. Thanks the comments to fix that.
@John Dauphine: I had implemented something very similar to your code, but switch to the current solution because a tryParse is much more efficient than a convert in a try/catch!

Post Comment

Title *
Name *
Email
Comment *  
Verification

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud