简体   繁体   English

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

[英]Reflection on a static overloaded method using an out parameter

I'm having some issues with invoking an overloaded static method with an out parameter via reflection and would appreciate some pointers. 我有一些问题,通过反射调用带有out参数的重载静态方法,并会欣赏一些指针。

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. 我想动态创建类似System.Int32System.Decimal的类型,然后在其上调用静态TryParse(string, out x)方法。

The below code has two issues: 以下代码有两个问题:

  • t.GetMethod("TryParse", new Type[] { typeof(string), t } ) fails to return the MethodInfo I expect t.GetMethod("TryParse", new Type[] { typeof(string), t } )无法返回我期望的MethodInfo

  • mi.Invoke(null, new object[] { value.ToString(), concreteInstance }) appears to succeed but doesn't set the out param concreteInstance to the parsed value mi.Invoke(null, new object[] { value.ToString(), concreteInstance })似乎成功但没有将out param concreteInstance设置为已解析的值

Interwoven into this function you can see some temporary code demonstrating what should happen if the type parameter was set to System.Decimal . 交织到此函数中,您可以看到一些临时代码,演示如果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;
}

What do I need to do to ensure that my t.GetMethod() call returns the correct MethodInfo? 我需要做些什么来确保我的t.GetMethod()调用返回正确的MethodInfo? What do I need to do to have concreteInstance correctly set in my mi.Invoke() call? 我需要做什么做有concreteInstance在我的设置正确mi.Invoke()调用?

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. 这个问题类似但不重复。

You need to use the right BindingFlags and use Type.MakeByRefType for out and ref parameters. 您需要使用正确的BindingFlags并使用Type.MakeByRefType作为outref参数。 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). 第一个null是因为我们正在调用静态方法(没有对象“接收”此调用)。 The null in inputParameters will be "filled" for us by TryParse with the result of the parse (it's the out parameter). inputParametersnull将由TryParse “填充”给我们解析的结果(它是out参数)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM