2011-01-19 6 views
14

리플렉션을 통해 out 매개 변수로 오버로드 된 정적 메서드를 호출 할 때 몇 가지 문제가 발생하며 일부 포인터에 감사드립니다.out 매개 변수를 사용하는 정적 오버로드 된 메서드에 대한 리플렉션

동적으로 System.Int32 또는 System.Decimal과 같은 유형을 만든 다음 정적 TryParse(string, out x) 메서드를 호출하려고합니다.

아래의 코드는 두 가지 문제가 있습니다

  • t.GetMethod("TryParse", new Type[] { typeof(string), t }) 내가

  • mi.Invoke(null, new object[] { value.ToString(), concreteInstance })

    성공에 나타나지만 분석 값으로 아웃 PARAM concreteInstance를 설정하지 않습니다 기대 MethodInfo를 반환하지를

이 기능에 짜 넣어서 어떤 임시 코드를 볼 수 있습니다. pen 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

BindingFlags 오른쪽을 사용하고 outref 매개 변수에 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이다. nullinputParametersTryParse에 의해 "채워짐"되며 구문 분석 결과는 out입니다.

+0

위대한 답변, thanks @ Jason. – slugster

관련 문제