locked
Generic TryParse for nullable types that returns null if parse fails

    Question

  • This is probably best explained by example. I'd like to be able to rewrite the following method in a generic fashion:

    1 public static int? TryParseNullable (string input)  
    2         {  
    3             if (input == nullreturn null;  
    4  
    5             int result;  
    6  
    7             bool parsable = Int32.TryParse(input, out result);  
    8  
    9             if (parsable)  
    10                 return result;  
    11             else 
    12                 return null;  
    13         } 

    Effectively this is a method which attempts to parse a string for an integer. If this is possible, the integer value is returned. Otherwise Null is returned.

    I would like to be able to do this for any nullable type (i.e. any Nullable<T>). E.g., to reproduce the result above, the generic method call might look like this:

    int? myResult = TryParseNullable<int?> (myString);

    I have attempted to do this and it is getting complex. I have a hunch I'm missing something simple.

    Note: the example I have given is unlike 'TryParse' in that it doesn't have an 'out' parameter. This is by design.


    Any thoughts much appreciated...
    Monday, July 14, 2008 7:00 PM

Answers

  • The problem with writing a method which can generically parse a Nullable type is that you then won't have what the unerlying type is in the generic method.  This is an issue since then we cannot convert the string to the type.  You can't convert a string to an int? (although the compiler makes you think so) you are actually converting to an int. 

    With that in mine, the closet I could get for you was being able to convert a string into a nullable type if you give the type you want it to convert to:

    1         public static Nullable<T> TryParseStruct<T>(string input)   
    2             where T: struct 
    3         {  
    4             if (string.IsNullOrEmpty(input))  
    5                 return default(T);  
    6  
    7             Nullable<T> result = new Nullable<T>();  
    8             try 
    9             {  
    10                 IConvertible convertibleString = (IConvertible)input;  
    11                 result = new Nullable<T>((T)convertibleString.ToType(typeof(T), CultureInfo.CurrentCulture));  
    12             }  
    13             catch(InvalidCastException)  
    14             {  
    15                   
    16             }  
    17             catch (FormatException)  
    18             {  
    19  
    20             }  
    21  
    22             return result;  
    23         } 

    -Matt
    • Marked as answer by jack 321 Friday, July 18, 2008 5:38 AM
    Monday, July 14, 2008 8:42 PM
    Moderator

All replies

  • The problem with writing a method which can generically parse a Nullable type is that you then won't have what the unerlying type is in the generic method.  This is an issue since then we cannot convert the string to the type.  You can't convert a string to an int? (although the compiler makes you think so) you are actually converting to an int. 

    With that in mine, the closet I could get for you was being able to convert a string into a nullable type if you give the type you want it to convert to:

    1         public static Nullable<T> TryParseStruct<T>(string input)   
    2             where T: struct 
    3         {  
    4             if (string.IsNullOrEmpty(input))  
    5                 return default(T);  
    6  
    7             Nullable<T> result = new Nullable<T>();  
    8             try 
    9             {  
    10                 IConvertible convertibleString = (IConvertible)input;  
    11                 result = new Nullable<T>((T)convertibleString.ToType(typeof(T), CultureInfo.CurrentCulture));  
    12             }  
    13             catch(InvalidCastException)  
    14             {  
    15                   
    16             }  
    17             catch (FormatException)  
    18             {  
    19  
    20             }  
    21  
    22             return result;  
    23         } 

    -Matt
    • Marked as answer by jack 321 Friday, July 18, 2008 5:38 AM
    Monday, July 14, 2008 8:42 PM
    Moderator
  • Minor tweak:

    4             if (string.IsNullOrEmpty(input))  
    5                 return null;  

    I like this pattern - works much better within the LINQ framework than the original out parameters.

    Rupert.

    Thursday, March 01, 2012 8:49 AM