使用out参数反映静态重载方法

slu*_*ter 14 c# reflection static-methods

我有一些问题,通过反射调用带有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 })似乎成功但没有将out参数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;
}
Run Code Online (Sandbox Code Playgroud)

我需要做些什么来确保我的t.GetMethod()调用返回正确的MethodInfo?concreteInstancemi.Invoke()呼叫中正确设置 我需要做什么?

我知道有很多关于这个主题的问题,但是大多数都涉及静态泛型方法或没有重载的静态方法.这个问题类似但不重复.

jas*_*son 29

您需要使用右侧BindingFlagsType.MakeByRefType用于outref参数.一秒钟,我将为您提供代码示例.

例如,

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

我应该指出,调用它也有点棘手.这是你如何做到的.

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

第一个null是因为我们正在调用一个静态方法(没有对象"接收"这个调用).将nullinputParameters将被"填满"我们通过TryParse与解析(它的结果out参数).