2012-07-14 5 views
8

TryParseを動的に呼び出す方法はありますか?いくつかの種類:TryParseを動的に呼び出す方法は?

public static bool TryParse<T>(string toConvert, out T result) 

もちろん、これにはTypeonvertersを使用できます。しかし、無効な変換は例外となり、私はこれを取り除きたい。

+0

多分あなたはSystem.Reflectionから何かを使うことができます。私はReflectionを使ってジェネリックを扱っていませんが、型情報を取得し、 'TryParse()'が存在すれば 'Invoke()'、そうでなければfalseを返します。 – cyanic

+0

関連:http://stackoverflow.com/a/6160588/445517 – CodesInChaos

+0

詳細はhttp://stackoverflow.com/a/2961921/103167をご覧ください。 –

答えて

9

Reflectionを使用してTryParseメソッドを動的に呼び出すことができます。変換が失敗した場合、この方法で時間のかかる例外が発生することはありません。

この方法は、このoneのやや最適化されたバージョンです。

//Try Parse using Reflection 
public static bool TryConvertValue<T>(string stringValue, out T convertedValue) 
{ 
    var targetType = typeof(T); 
    if (targetType == typeof(string)) 
    { 
     convertedValue = (T)Convert.ChangeType(stringValue, typeof(T)); 
     return true; 
    } 
     var nullableType = targetType.IsGenericType && 
         targetType.GetGenericTypeDefinition() == typeof (Nullable<>); 
    if (nullableType) 
    { 
     if (string.IsNullOrEmpty(stringValue)) 
     { 
      convertedValue = default(T); 
      return true; 
     } 
      targetType = new NullableConverter(targetType).UnderlyingType; 
    } 

    Type[] argTypes = { typeof(string), targetType.MakeByRefType() }; 
    var tryParseMethodInfo = targetType.GetMethod("TryParse", argTypes); 
    if (tryParseMethodInfo == null) 
    { 
     convertedValue = default(T); 
     return false; 
    } 

    object[] args = { stringValue, null }; 
    var successfulParse = (bool)tryParseMethodInfo.Invoke(null, args); 
    if (!successfulParse) 
    { 
     convertedValue = default(T); 
     return false; 
    } 

    convertedValue = (T)args[1]; 
    return true; 
} 
+0

良い提案: 'if(nullableType)'ブロックで 'stringValue'を' null'にチェックすると、おそらく 'string.IsNullOrEmpty(stringValue)'と言うべきでしょう。私がそう思うのは、 'Nullable <> ToString()'は、 'HasValue'がfalseのとき' '' 'を返します。空の文字列は、例えば、 '(int?)null'。 –

+1

入力いただきありがとうございます。しかし、Nullableを変換するために ""を使用してこのメ​​ソッドを呼び出すと、出力値はnullになり、戻り値はfalseになります。これは正しいですが、intを解析するための有効な値ではないはずです。私がstring.IsNullOrEmptyを使用する場合、戻り値は真であり、正しいimhoではありません。 –

+1

それは完全にOKです。しかし、Nullable は往復しないことを意味します。あなたは 'int? i = null;文字列s = i.ToString(); int? tmp; bool canParse = TryConvertValue (s、out tmp); '。文字列 's'が' int'の 'ToString'呼び出しから直接得られたとしても、' canParse'はfalseになります。 [MSDN ToString](http://msdn.microsoft.com/en-us/library/9hd15ket.aspx)も参照してください。 –

2

あなたはこのような何か書くことができます。

public delegate bool TryParser<T>(string input, out T result); 

public static bool TryParse<T> 
    (string toConvert, out T result, TryParser<T> tryParser = null) 
{ 
    if (toConvert == null) 
     throw new ArgumentNullException("toConvert"); 

    // This whole block is only if you really need 
    // it to work in a truly dynamic way. You can additionally consider 
    // memoizing the default try-parser on a per-type basis. 
    if (tryParser == null) 
    { 
     var method = typeof(T).GetMethod 
       ("TryParse", new[] { typeof(string), typeof(T).MakeByRefType() }); 

     if (method == null) 
      throw new InvalidOperationException("Type does not have a built in try-parser."); 

     tryParser = (TryParser<T>)Delegate.CreateDelegate 
      (typeof(TryParser<T>), method); 
    } 

    return tryParser(toConvert, out result); 
} 

をそして同じようにそれを呼び出す:あなたがそれを必要とするいくつかのシナリオを持っていない限り、私は本当にこのことをお勧めしません

int result; 
bool success = TryParse("123", out result); 

+0

これはすばらしい発見でした。とても有難い。 – BackDoorNoBaby

関連する問題