Default (T) by mirrored type

While looking at other answers, I came up with the following extension method, which works with pleasure:

public static T Convert<T>( this string input ) { var converter = TypeDescriptor.GetConverter( typeof( T ) ); if ( converter != null ) { try { T result = (T) converter.ConvertFromString( input ); return result; } catch { return default( T ); } } return default( T ); } 

And I can use it like:

 string s = "2011-09-21 17:45"; DateTime result = s.ConvertTo( typeof( DateTime ) ); if ( result == DateTime.MinValue ) doSomethingWithTheBadData(); 

Awesome! It works great. Now I would like to do something similar with a mirrored type. I have:

 public static dynamic ConvertTo( this string input, Type type ) { var converter = TypeDescriptor.GetConverter( type ); if ( converter != null ) { try { dynamic result = converter.ConvertFromString( input ); return ( result ); } catch { return default( type ); // bogus } } return default( type ); // bogus } 

And I would like to use it this way:

 Type someType; // will be DateTime, int, etc., but not known until runtime DateTime result = s.ConvertTo( sometype ); if ( result == DateTime.MinValue ) doSomethingWithTheBadData(); 

Of course, the compiler refers to the "dummy" lines in the ConvertTo method. What I need (normal, not necessarily necessary, but it would be nice) is a way to get the same result as in the first example, so if the conversion fails, it returns what can be assigned to the reflected object and can be recognized same as in the first example.

Edit:

What I ended up with:

 public static dynamic ConvertTo( this string input, Type type, out bool success ) { dynamic result; var converter = TypeDescriptor.GetConverter( type ); if ( converter != null ) { try { result = converter.ConvertFromString( input ); success = true; return result; } catch { /* swallow the exception */ } } result = type.IsValueType ? Activator.CreateInstance( type ) : null; success = false; return result; } 

and used:

 bool success; string val = "2011-09-21 17:25"; dateTime = val.ConvertTo( typeof( DateTime ), out success ); if ( success ) doSomethingGood(); val = "foo"; dateTime = val.ConvertTo( typeof( DateTime ), out success ); if ( !success ) dealWithBadData(); 

Remembering that for demonstration I hardcode the typeof () bit. In my application, all types are reflected.

Thanks everyone for the quick answers!

+4
source share
3 answers

Unconfirmed, but maybe something like this?

 public static dynamic ConvertTo(this string input, Type type) { var converter = TypeDescriptor.GetConverter(type); if (converter != null) { try { return converter.ConvertFromString(input); } catch { // ignore } } if (type.IsValueType) return Activator.CreateInstance(type); return null; } 
+2
source

you can use

 //to get default(T) from an instance of Type type.IsValueType ? Activator.CreateInstance(type) : null; 

This is because there is guaranteed to be a default constructor for value types, and the default value for a reference type is null .

+9
source

If you pass a type using typeof(Type) , then obviously you can just use the first method. Assuming you get the type through reflection (what you say you are), you can also use reflection to get MethodInfo for your first version of Convert() , and then use MakeGenericMethod() to replace your reflected in it:

 MethodInfo m = typeof(MyConvertExtensions).GetMethod("Convert"); MethodInfo invocable = m.MakeGenericMethod(myReflectedType); invocable.Invoke(null, new[] { myString }); 
+4
source

All Articles