Reflection on a static overloaded method using an out parameter

戏子无情 提交于 2019-11-30 13:13:07

问题


I'm having some issues with invoking an overloaded static method with an out parameter via reflection and would appreciate some pointers.

I'm looking to dynamically create a type like System.Int32 or System.Decimal, and then invoke the static TryParse(string, out x) method on it.

The below code has two issues:

  • t.GetMethod("TryParse", new Type[] { typeof(string), t } ) fails to return the MethodInfo I expect

  • mi.Invoke(null, new object[] { value.ToString(), concreteInstance }) appears to succeed but doesn't set the out param concreteInstance to the parsed value

Interwoven into this function you can see some temporary code demonstrating what should happen if the type parameter was set to 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;
}

What do I need to do to ensure that my t.GetMethod() call returns the correct MethodInfo? What do I need to do to have concreteInstance correctly set in my mi.Invoke() call?

I know there are a bunch of questions on this topic, but most of them involve static generic methods or static methods that are not overloaded. This question is similar but not a duplicate.


回答1:


You need to use the right BindingFlags and use Type.MakeByRefType for out and ref parameters. One second, and I'll have a code sample for you.

For example,

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

I should point out that invoking this is a little tricky too. Here's how you do it.

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

The first null is because we are invoking a static method (there is no object "receiving" this invocation). The null in inputParameters will be "filled" for us by TryParse with the result of the parse (it's the out parameter).



来源:https://stackoverflow.com/questions/4740510/reflection-on-a-static-overloaded-method-using-an-out-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!