2011-01-19 4 views
14

私は、リフレクションによってoutパラメータを使用してオーバーロードされた静的メソッドを呼び出す際にいくつかの問題を抱えています。outパラメータを使用した静的なオーバーロードされたメソッドのリフレクション

私は、System.Int32またはSystem.Decimalのようなタイプを動的に作成し、その上にスタティックTryParse(string, out x)メソッドを呼び出すことを検討しています。

は、以下のコードは二つの問題があります。

  • t.GetMethod("TryParse", new Type[] { typeof(string), t })をMETHODINFOを返すことに失敗した私は

  • mi.Invoke(null, new object[] { value.ToString(), concreteInstance })が成功したように見えるが解析された値

  • にアウトPARAM concreteInstanceを設定しません期待します

この機能に組み込まれていることで、何が起こるべきかを示す一時的なコードが表示されますペンtypeパラメータがSystem.Decimalに設定されている場合。

public static object Cast(object value, string type) 
{ 
    Type t = Type.GetType(type); 
    if (t != null) 
    { 
     object concreteInstance = Activator.CreateInstance(t); 
     decimal tempInstance = 0; 

     List<MethodInfo> l = new List<MethodInfo>(t.GetMethods(BindingFlags.Static | BindingFlags.Public)); 

     MethodInfo mi; 
     mi = t.GetMethod("TryParse", new Type[] { typeof(string), t }); //this FAILS to get the method, returns null 
     mi = l.FirstOrDefault(x => x.Name == "TryParse" && x.GetParameters().Length == 2); //ugly hack required because the previous line failed 
     if (mi != null) 
     { 
      try 
      { 
       bool retVal = decimal.TryParse(value.ToString(), out tempInstance); 
       Console.WriteLine(retVal.ToString());  //retVal is true, tempInstance is correctly set 
       object z = mi.Invoke(null, new object[] { value.ToString(), concreteInstance }); 
       Console.WriteLine(z.ToString());   //z is true, but concreteInstance is NOT set 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine(ex.Message); 
      } 
     } 

     return concreteInstance; 
    } 

    return value; 
} 

t.GetMethod()呼び出しが正しいMethodInfoを返すためには、どうすればよいですか?私のmi.Invoke()コールにconcreteInstanceを正しく設定するには何が必要ですか?

私はこのトピックについてたくさんの質問があることを知っていますが、それらのほとんどは、静的な汎用メソッドまたは過負荷ではない静的メソッドを含みます。 This questionは類似していますが、重複はありません。

答えて

26

右を使用し、とrefパラメータにはType.MakeByRefTypeを使用する必要があります。 1秒間、コードサンプルがあります。

例えば、

MethodInfo methodInfo = typeof(int).GetMethod(
    "TryParse", 
    BindingFlags.Public | BindingFlags.Static, 
    Type.DefaultBinder, 
    new[] { typeof(string), typeof(int).MakeByRefType() }, 
    null 
); 

は、私はこれを呼び出すことは、あまりにも少しトリッキーであることを指摘すべきです。あなたのやり方は次のとおりです。

string s = "123"; 
var inputParameters = new object[] { "123", null }; 
methodInfo.Invoke(null, inputParameters); 
Console.WriteLine((int)inputParameters[1]); 

最初null我々は静的メソッドを呼び出しているので(この呼び出しを「受信」オブジェクトがない)です。 nullinputParametersは、TryParseによって解析され、結果は解析結果となります(outパラメータ)。

+0

偉大な答え、感謝@ジェイソン。 – slugster

関連する問題