简体   繁体   中英

Parsing/Converting string into Generic nullable type falling back to UnderlyingType default

Looking for a 'one-liner' to use GetValueOrDefault() in the scenario below. It is a LINQPad script you should just be able to drop in.

void Main()
{
    Foo<string>( null ).Dump();
    Foo<string>( "Hello" ).Dump();
    Foo<double?>( "" ).Dump();
    Foo<double?>( "10" ).Dump();
    Foo<DateTime?>( "" ).Dump();
    Foo<DateTime?>( "2014-01-01" ).Dump();  
}

// Define other methods and classes here
public T Foo<T>( string value )
{
    var changeType = typeof( T );
    var convertType = IsNullable( changeType )
        ? new System.ComponentModel.NullableConverter( typeof( T ) ).UnderlyingType
        : changeType;

    if ( string.IsNullOrEmpty( value ) && IsNullable( changeType ) )
    {
        // Wanted to do this...couldn't figure out how to get 0 or min date for double?/datetime?
        // return default( T ).GetValueOrDefault(); would be obvious choice, but compiler doesn't know
        // T is nullable so the GetValueOrDefault() extension isn't available.
        if ( changeType == typeof( DateTime? ) )
        {
            return (T)(object)DateTime.MinValue;
        }
        else 
        {
            return (T)(object)0d;
        }
    }
    else
    {
        return (T)Convert.ChangeType( value, convertType );
    }
}
private bool IsNullable( Type type )
{
  return ( type != null && type.IsGenericType && type.GetGenericTypeDefinition().Equals( typeof( Nullable<> ) ) );
}

The following works for me, note Activator.CreateInstance :

public T Foo<T>(string value) 
{
    var changeType = typeof(T);
    var convertType = IsNullable(changeType)
        ? new System.ComponentModel.NullableConverter(typeof(T)).UnderlyingType
        : changeType;

    if (string.IsNullOrEmpty(value) && IsNullable(changeType))
    {
        var defValue = Activator.CreateInstance(
            Nullable.GetUnderlyingType(changeType));
        return (T)defValue;
    }
    else
    {
        return (T)Convert.ChangeType(value, convertType);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM