In browsing other answers, I have come up with the following extension method which works a treat:
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! Works great. Now, I'd like to do something similar with a reflected 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'd like to use it thus:
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 objects to the 'bogus' lines in the ConvertTo method. What I need (ok, don't necessarily need, but it'd be nice) is a way to get the same result as in the first example so that if the conversion fails, something that can be assigned to the reflected object is returned and can be recognized in the same manner as in the first example.
Edit:
What I finished 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 the purpose of demonstration, I'm hard-coding the typeof() bit. In my application, the types are all reflected.
Thanks to all for the speedy answers!
You can use
//to get default(T) from an instance of Type
type.IsValueType ? Activator.CreateInstance(type) : null;
This is because value types are guaranteed to have a default constructor, and the default value of a reference type is a null.
If you're passing in the type using typeof(Type), then obviously you could just use the first method. Assuming, then, that you're getting the type via reflection (which you say you are) then you can also use reflection to get the MethodInfo for your first version of Convert(), and then use MakeGenericMethod() to substitute your reflected type into it:
MethodInfo m = typeof(MyConvertExtensions).GetMethod("Convert");
MethodInfo invocable = m.MakeGenericMethod(myReflectedType);
invocable.Invoke(null, new[] { myString });
Untested, 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;
}
Related
I want to optimise this code to reduce the number of if statements. Maybe it'd be better to use a lot of classes, and let the classes handle each required action?
It could be fabric pattern? Or is it OK to use 30+ similar if statements?
I've tried to make a Dictionary with string and object class. But I couldn't get it to work (or my skills are not good enough)
if (node[DATA_CONNECTION_ELEMENT] != null)
{
return new DataConnectionPropertyDataBinding(form, node[DATA_CONNECTION_ELEMENT], inputableEntity);
}
else if (node[FORM_PARAMETER_ELEMENT] != null)
{
return new FormParameterDataBinding(form, node[FORM_PARAMETER_ELEMENT], inputableEntity);
}
// + 30 more else ifs
else if (node[COMMAND_ELEMENT] != null)
{
return new CommandResultDataBinding(form, node[COMMAND_ELEMENT], inputableEntity);
}
else if (node[CONDITION_ELEMENT] != null)
{
return new ConditionDataBinding(form, node[CONDITION_ELEMENT], inputableEntity);
}
else if (node[CLIPBOARD_ELEMENT] != null)
{
return new ClipboardDataBinding(form, node[CLIPBOARD_ELEMENT], inputableEntity);
}
else
{
return new ConstantDataBinding(form, node);
}
Want to make it look something like
foreach (var item in allThatShareSomeInterface)
{
if (item.CanHandle(node.Atributes[0]))
{
return item.neededObject();
}
}
Here is the answer. How it really works.
Dictionary<string, Type> allObjects = new Dictionary<string, Type>();
allObjects.Add(CONDITION_ELEMENT, typeof(ConditionDataBinding));
allObjects.Add(DATA_TYPE_FORMAT_ELEMENT, typeof(DataTypeFormatDataBinding));
allObjects.Add(DATA_TYPE_CONVERT_ELEMENT, typeof(DataTypeConvertDataBinding));
allObjects.Add(FORM_PARAMETER_ELEMENT, typeof(FormParameterDataBinding));
allObjects.Add(FORM_ELEMENT, typeof(FormPropertyDataBinding));
allObjects.Add(STRING_ELEMENT, typeof(StringFormatDataBinding));
allObjects.Add(FORMULA_ELEMENT, typeof(FormulaDataBinding));
allObjects.Add(COMMAND_ELEMENT, typeof(CommandResultDataBinding));
// + many
foreach (var pair in allObjects)
{
if (node[pair.Key] != null)
{
ConstructorInfo ctor = pair.Value.GetConstructor(new[] { typeof(IWorkflowForm), typeof(XmlNode), typeof(IInputable) });
return ctor.Invoke(new object[] { form, node[pair.Key], inputableEntity });
}
}
You may be able to make this work using reflection. It's probably going to make your code a bit slower though.
It should look something like this (not tested):
var pairs = new Dictionary<string, Type>()
{
{
DATA_CONNECTION_ELEMENT, typeof(DataConnectionPropertyDataBinding)
},
{
FORM_PARAMETER_ELEMENT, typeof(FormParameterDataBinding)
}
};
foreach (var pair in pairs)
{
if (node[pair.Key] != null)
{
ConstructorInfo ctor = pair.Value.GetConstructor(new[] { typeof(object), typeof(object), typeof(object) });
return ctor.Invoke(new object[] { form, node[pair.Key], inputableEntity });
}
}
If you know what you are doing, and you indeed need that many binding classes, one way to solve that is custom attributes + reflection + runtime code generation. Here’s an example.
// Enum for element type. The order matters, it's the order in which input dictionary is tested.
enum eElement
{
DataConnection,
FormParameter,
}
// Custom attribute to mark bindings classes with.
class DataBindingAttribute : Attribute
{
public eElement element;
public DataBindingAttribute( eElement e ) { element = e; }
}
// Base class for bindings
abstract class BindingBase { }
// Couple test binding classes
[DataBinding( eElement.DataConnection )]
class DataConnectionPropertyDataBinding: BindingBase
{
public DataConnectionPropertyDataBinding( object data ) { }
}
[DataBinding( eElement.FormParameter )]
class FormParameterDataBinding: BindingBase
{
public readonly object data;
public FormParameterDataBinding( object data ) { this.data = data; }
}
// This static class does the magic.
static class BindingsFactory
{
// Key = eElement from custom attribute, value = function that constructs the binding. This example uses the constructor with single object argument.
// It's a good idea to use strong types for arguments instead.
static readonly SortedDictionary<eElement, Func<object, BindingBase>> dictTypes = new SortedDictionary<eElement, Func<object, BindingBase>>();
static BindingsFactory()
{
// Constructor argument types, just a single `object` in this example.
Type[] constructorArgumentTypes = new Type[ 1 ]
{
typeof( object )
};
ParameterExpression[] constructorArgumentExpressions = constructorArgumentTypes
.Select( tp => Expression.Parameter( tp ) )
.ToArray();
// Find all types in current assembly
var ass = Assembly.GetExecutingAssembly();
foreach( Type tp in ass.GetTypes() )
{
// Try to get the custom attribute
var dba = tp.GetCustomAttribute<DataBindingAttribute>();
if( null == dba )
continue;
// Ensure you don't have 2 classes with the same element ID value
Debug.Assert( !dictTypes.ContainsKey( dba.element ) );
// Ensure the found type inherits from BindingBase
Debug.Assert( typeof( BindingBase ).IsAssignableFrom( tp ) );
// Compile the function that constructs the new binding object
ConstructorInfo ci = tp.GetConstructor( constructorArgumentTypes );
Debug.Assert( null != ci );
// new Binding(...)
var expNew = Expression.New( ci, constructorArgumentExpressions );
// (BindingBase)( new Binding( ... ) )
var expCast = Expression.Convert( expNew, typeof( BindingBase ) );
// Compile into lambda
var lambda = Expression.Lambda<Func<object, BindingBase>>( expCast, constructorArgumentExpressions );
// Compile the lambda, and save in the sorted dictionary
var func = lambda.Compile();
dictTypes.Add( dba.element, func );
}
}
public static BindingBase tryConstruct( Dictionary<eElement, object> dict )
{
foreach( var kvp in dictTypes )
{
object arg;
if( !dict.TryGetValue( kvp.Key, out arg ) )
continue;
return kvp.Value( arg );
}
return null;
}
}
class Program
{
static void Main( string[] args )
{
var dict = new Dictionary<eElement, object>();
dict[ eElement.FormParameter ] = 12;
// This line will construct an instance of FormParameterDataBinding
var res = BindingsFactory.tryConstruct( dict );
}
}
I have the following function. I would like to call and convert a string to int32. How to do I call this function?
static Func GetConverter(T example)
static Func<string, T> GetConverter<T>(T example)
{
return (x) => Convert<T>(x);
}
This is the code used for converting. I got this code from StackOverflow but not sure how to use.
static T Convert<T>(string val)
{
Type destiny = typeof(T);
// See if we can cast
try
{
return (T)(object)val;
}
catch { }
// See if we can parse
try
{
return (T)destiny.InvokeMember("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
}
catch { }
// See if we can convert
try
{
Type convertType = typeof(Convert);
return (T)convertType.InvokeMember("To" + destiny.Name, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
}
catch { }
// Give up
return default(T);
}
If you must to use GetConverter method, you should first call it to get converter function.
Assuming GetConverter is under class named A:
int value = 0;
var converter = A.GetConverter(value);
then you can call the converter from GetConverter method like a local function:
value = converter("123");
I think you don't have to pass a parameter to GetConverter function. This implementation is better since you dont use example parameter:
static Func<string, T> GetConverter<T>()
{
return (x) => Convert<T>(x);
}
So now you can use it like:
var converter = A.GetConverter<int>();
int value = converter("123");
PS: You can use int.TryParse method instead if you know the target (int) and source (string) types. Or you can use the converter function itself without getting another function to wrap it, like: Convert< int >("123")
I'm looking for more generic/"standard" way to instantiate object of some type T from set of pairs string,object. For me it looks like there should be some well known way to do it but I cannot find it, so I come up with this piece of code.
Does anybody know something better?
// usage
public class test
{
public int field1;
public string field2;
public bool field3;
public string[] field4;
public IDictionary<string,object> field5 { get; set; }
public static IDictionary<string,object> dynamic()
{
return new Dictionary<string,object>{
{ "field1", 2 },
{ "field2", "string" },
{ "field3", true },
{ "field4", new[] { "id3", "id4", "id5" } },
{ "field5", new Dictionary<string,object>{ { "id1", "" } } }
};
}
}
...
var r = new dynamic_data_serializer<test>().create( test.dynamic() );
...
//
public class dynamic_data_serializer< T >
{
public T create( object obj )
{
var result = default(T);
if ( obj == null )
return result;
var ttype = typeof(T);
var objtype = obj.GetType();
if ( ttype.IsAssignableFrom( objtype ) ) {
result = (T)obj;
return result;
}
if ( ttype.IsClass ) { // custom classes, array, dictionary, etc.
result = Activator.CreateInstance<T>();
if ( objtype == typeof(IDictionary<string,object>) ||
objtype == typeof(Dictionary<string,object>) ) {
var obj_as_dict = obj as IDictionary<string,object>;
var fields = ttype.GetFields();
if ( fields.Length > 0 )
set_fields_from( result, fields, obj_as_dict );
var properties = ttype.GetProperties();
if ( properties.Length > 0 )
set_properties_from( result, properties, obj_as_dict );
}
}
return result;
}
private void set_fields_from( T _this_, FieldInfo[] fields, IDictionary<string,object> obj ) {
foreach ( var fld in fields ) {
var v = find( obj, fld.Name );
if ( v != null ) {
var mobj = call_deserialize( fld.FieldType, v );
fld.SetValue( _this_, mobj );
}
}
}
private void set_properties_from( T _this_, PropertyInfo[] properties, IDictionary<string,object> obj ) {
foreach ( var prop in properties ) {
var v = find( obj, prop.Name );
if ( v != null ) {
var mobj = call_deserialize( prop.PropertyType, v );
prop.SetValue( _this_, mobj, null );
}
}
}
private object find( IDictionary<string,object> obj, string name ) {
foreach ( var kv in obj )
if ( string.Compare( kv.Key, name, true ) == 0 )
return kv.Value;
return null;
}
private object call_deserialize( Type des_type, object value ) {
var gtype = typeof(dynamic_data_serializer<>);
Type desz_type = gtype.MakeGenericType( new[]{ des_type } );
object desz = Activator.CreateInstance( desz_type );
var method_type = desz_type.GetMethod( "create" );
return method_type.Invoke( desz, new[]{ value } );
}
}
}
DataContractJsonSerializer is too slow, but you're using reflection? If you have to deserialize lots of objects, I would recommend using compiled lambdas instead of reflection. A lambda can only set properties, not fields (at least in .Net 3.5), so you may have to adjust the classes you use it on, but it's worth it because it's like 1000 times faster.
Here's a function that creates a property setter given a type and a PropertyInfo for the property to set:
static Action<object, TValue> MakeSetter<TValue>(Type tclass, PropertyInfo propInfo)
{
var t = lambda.Expression.Parameter(typeof(object), "t");
var v = lambda.Expression.Parameter(typeof(TValue), "v");
// return (t, v) => ((tclass)t).prop = (tproperty)v
return (Action<object, TValue>)
lambda.Expression.Lambda(
lambda.Expression.Call(
lambda.Expression.Convert(t, tclass),
propInfo.GetSetMethod(),
lambda.Expression.Convert(v, propInfo.PropertyType)),
t,
v)
.Compile();
}
You would have a dictionary of setters for each class, and whenever you have to set a property of a class, you would look up the setter for that property in the dictionary and call it with the value to assign, like this: setters[propName](_this_, value);
I might suggest FormatterServices.PopulateObjectMembers, except a: this is still slow AFAIK, and b: I tried it (below) and it seems to want to throw an exception on the property (don't know why; didn't look too deep). Another option may be Expression, but you don't really want to do the Compile each time (better to do it once only and cache it, but that demands a known format).
public T create(object obj)
{ // simplified for illustration
var bindings = obj as IDictionary<string, object>;
Type type = typeof(T);
var func = Expression.Lambda<Func<T>>(Expression.MemberInit(
Expression.New(type),
from pair in bindings
let member = type.GetMember(pair.Key).Single()
select (MemberBinding)Expression.Bind(member, Expression.Constant(pair.Value))));
return func.Compile().Invoke();
}
Finally, you might cache a set of pre-compiled Action<object> setters (keyed against the member name). In reality this is probably your best bet. Properties are easy (you use Delegate.CreateDelegate) - fields might need DynamicMethod - but if you can't predict the layout in advance it'll have the least overhead.
For the keyed / IL approach (you won't get faster):
public class dynamic_data_serializer<T>
{
public T create(object obj)
{
T inst = Activator.CreateInstance<T>();
var bindings = obj as IDictionary<string, object>;
foreach (var pair in bindings)
{
setters[pair.Key](inst, pair.Value);
}
return inst;
}
private static readonly Dictionary<string, Action<T, object>> setters;
static dynamic_data_serializer()
{
setters = new Dictionary<string, Action<T, object>>(StringComparer.Ordinal);
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
setters.Add(prop.Name, CreateForMember(prop));
}
foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance)) {
setters.Add(field.Name, CreateForMember(field));
}
}
static Action<T, object> CreateForMember(MemberInfo member)
{
bool isField;
Type type;
switch (member.MemberType) {
case MemberTypes.Property:
isField = false;
type = ((PropertyInfo)member).PropertyType;
break;
case MemberTypes.Field:
isField = true;
type = ((FieldInfo)member).FieldType;
break;
default:
throw new NotSupportedException();
}
DynamicMethod method = new DynamicMethod("__set_" + member.Name, null, new Type[] { typeof(T), typeof(object) });
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
if(type != typeof(object)) {
il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
}
if (isField) {il.Emit(OpCodes.Stfld, (FieldInfo)member);}
else { il.EmitCall(OpCodes.Callvirt, ((PropertyInfo)member).GetSetMethod(), null); }
il.Emit(OpCodes.Ret);
return (Action<T, object>)method.CreateDelegate(typeof(Action<T, object>));
}
}
DataContractJsonSerializer
Why would you make a custom serializer and not use the DataContractJsonSerializer?
EDIT
If DataContractJsonSerializer doesn't fit you, you can try JSON.Net. Implementing a serializer efficiently is not an easy task, there's a lot of pitfalls and special cases that you may not want to get into. By the way, your code sample makes heavy use of reflection which is slow, I doubt that it will perform better than DataContractJsonSerializer or JSON.Net.
an example code what I try to do will surely do better than my english:
public bool IsNumericValueInBounds (string value, Type numericType)
{
double d = double.NaN;
bool inBounds = (bool)numericType.GetMethod ("TryParse").Invoke (null, new object[] { value, d });
return inBounds;
}
Unfortunately the TryParse method needs an out parameter so this doesn't work.
any ideas how to solve this?
(ps.: would'nt this be a nice example for duck typing? - because i know every numericType has an "TryParse" or I am mistaken?)
public static bool TryParse( string text, out int number ) { .. }
MethodInfo method = GetTryParseMethodInfo();
object[] parameters = new object[]{ "12345", null }
object result = method.Invoke( null, parameters );
bool blResult = (bool)result;
if ( blResult ) {
int parsedNumber = (int)parameters[1];
}
My particular problem:
I have a string which specifies an aribitrary type in a configuration class
Config.numberType = "System.Foo";
where Foo is a type like Decimal or Double
I use Type.GetType(Config.numberType) to return the corresponding type.
How do I get from that type to being able to use, System.Foo.TryParse() ?
Some further related queries
TryParse() can be accessed from System.Foo.TryParse() as well as foo.TryParse(). Does this mean foo is some kind of class in C#? This seems weird to me that int, double etc are actually not just modifier keywords.
How can you declare variables under these circumstances? - var is not universally usable it seems i.e. only in local scope etc.
As many have said - there isn't a direct route. I expect one close option is TypeConverter:
Type type = typeof(double);
string text = "123.45";
object value = TypeDescriptor.GetConverter(type)
.ConvertFromInvariantString(text);
Of course, you may need try/catch to handle exceptions. Such is life.
How do I get from that type to being
able to use, System.Foo.TryParse() ?
You'll need to use reflection to look up and then invoke the static TryParse() method. Not all types implement this method - so you'll have to decide how to handle it if it's missing. You could also use System.Convert to convert a string to an arbitrary type, assuming the string is actually a valid representation of a value for that type and there's a conversion implemented for it.
TryParse() can be accessed from
System.Foo.TryParse() as well as
foo.TryParse(). Does this mean foo is
some kind of class in C#?
int, double, etc. are aliases for System.Int32, System.Double, etc. - they're part of the C# language, which would be uncomfortably verbose without them.
How can you declare variables under
these circumstances?
Without knowing the type at compile-time, you'll be forced to declare and work with your data as object / System.Object. C# 4.0 will introduce actual dynamic types that will take care of some of the tedious reflection work for you, but for now you're stuck doing it by hand. Note that if you use System.Convert in a method with a parametrized type argument and return, or TryParse() using a technique such as that linked to by Sebastian Sedlak, you can easily achieve the ability to write client code that works with static types... So long as they match or can be converted to from the types you're parsing.
EDITED: I removed the generic implementation and cleaned up this response to fit better to the originally stated problem.
NOTE: The answer by Marc Gravell is probably the most concise if you just want the parsed value given the type. The answer below shows you how to get at the method (i.e., the MethodInfo object and how to invoke it).
The following should work, at least for types that implement public static bool TryParse(string, T value):
public static class Parsing
{
static MethodInfo findTryParseMethod(Type type)
{
//find member of type with signature 'static public bool TryParse(string, out T)'
BindingFlags access = BindingFlags.Static | BindingFlags.Public;
MemberInfo[] candidates = type.FindMembers(
MemberTypes.Method,
access,
delegate(MemberInfo m, object o_ignored)
{
MethodInfo method = (MethodInfo)m;
if (method.Name != "TryParse") return false;
if (method.ReturnParameter.ParameterType != typeof(bool)) return false;
ParameterInfo[] parms = method.GetParameters();
if (parms.Length != 2) return false;
if (parms[0].ParameterType != typeof(string)) return false;
if (parms[1].ParameterType != type.MakeByRefType()) return false;
if (!parms[1].IsOut) return false;
return true;
}, null);
if (candidates.Length > 1)
{
//change this to your favorite exception or use an assertion
throw new System.Exception(String.Format(
"Found more than one method with signature 'public static bool TryParse(string, out {0})' in type {0}.",
type));
}
if (candidates.Length == 0)
{
//This type does not contain a TryParse method - replace this by your error handling of choice
throw new System.Exception(String.Format(
"Found no method with signature 'public static bool TryParse(string, out {0})' in type {0}.",
type));
}
return (MethodInfo)candidates[0];
}
public static bool TryParse(Type t, string s, out object val)
{
MethodInfo method = findTryParseMethod(t); //can also cache 'method' in a Dictionary<Type, MethodInfo> if desired
object[] oArgs = new object[] { s, null };
bool bRes = (bool)method.Invoke(null, oArgs);
val = oArgs[1];
return bRes;
}
//if you want to use TryParse in a generic syntax:
public static bool TryParseGeneric<T>(string s, out T val)
{
object oVal;
bool bRes = TryParse(typeof(T), s, out oVal);
val = (T)oVal;
return bRes;
}
}
Use the following test code:
public bool test()
{
try
{
object oVal;
bool b = Parsing.TryParse(typeof(int), "123", out oVal);
if (!b) return false;
int x = (int)oVal;
if (x!= 123) return false;
}
catch (System.Exception)
{
return false;
}
try
{
int x;
bool b = Parsing.TryParseGeneric<int>("123", out x);
if (!b) return false;
if (x != 123) return false;
}
catch (System.Exception)
{
return false;
}
try
{
object oVal;
bool b = Parsing.TryParse(typeof(string), "123", out oVal);
//should throw an exception (//no method String.TryParse(string s, out string val)
return false;
}
catch (System.Exception)
{
//should throw an exception
}
return true;
}
}
And use this in your case:
//input: string s, Config
Type tNum = Type.GetType(Config.numberType);
object oVal;
bool ok = Parsing.TryParse(tNum, s, out oVal);
//oVal is now of type tNum and its value is properly defined if ok == true
About the use of var: you may have a misconception of what var does: It is not a "variant" type (the type object already is used for that) but moves the declaration syntax for the type to the assignment's right side. The following declarations are equivalent:
var i = 1; //the compiler infers the type from the assignment, type of i is int.
int i = 1; //type of i is int via declaration
The primary use of var is allowing to create anonymous types:
var anon = new { Name = "abc", X = 123 };
And another good link to this problem. The source code on that site is very bad formatted, so i putted it here. Hopefully, the author doesn't sue me.
public static T Parse<T>(string s)
{
Type t = typeof(T);
// Attempt to execute the Parse method on the type if it exists.
MethodInfo parse = t.GetMethod("Parse", new Type[] { typeof(string) });
if (parse != null)
{
try
{
return (T)parse.Invoke(null, new object[] { s });
}
catch (Exception ex)
{
throw ex.InnerException;
}
}
else
{
throw new MethodAccessException(String.Format("The Parse method does not exist for type {0}.", t.Name));
}
}
public static bool TryParse<T>(string s, out T result)
{
return TryParse<T>(s, false, out result);
}
public static bool TryParse<T>(string s, bool throwException, out T result)
{
result = default(T);
Type t = typeof(T);
T type = default(T);
// Look for the TryParse method on the type.
MethodInfo tryParse = t.GetMethod("TryParse", new Type[] { typeof(string), Type.GetType(t.FullName + "&") });
if (tryParse != null)
{
// Try parse exists. Call it.
Object[] ps = new Object[2];
ps[0] = s;
bool isSuccess = (bool)tryParse.Invoke(type, ps);
if (isSuccess)
result = (T)ps[1];
return isSuccess;
}
else
{
// TryParse does not exist. Look for a Parse method.
try
{
result = Parse<T>(s);
return true;
}
catch
{
if (throwException)
throw;
return false;
}
}
}
this may help: http://theengineroom.provoke.co.nz/archive/2007/04/27/generic-tryparse-type-conversion.aspx