C# 关于使用out参数的静态重载方法的思考

C# 关于使用out参数的静态重载方法的思考,c#,reflection,static-methods,C#,Reflection,Static Methods,我在通过反射调用带有out参数的重载静态方法时遇到了一些问题,希望能提供一些指针 我希望动态创建一个类型,如System.Int32或System.Decimal,然后在其上调用静态TryParse(string,out x)方法 以下代码有两个问题: t.GetMethod(“TryParse”,新类型[]{typeof(string),t})无法返回我期望的MethodInfo mi.Invoke(null,新对象[]{value.ToString(),concreteInstance})

我在通过反射调用带有out参数的重载静态方法时遇到了一些问题,希望能提供一些指针

我希望动态创建一个类型,如
System.Int32
System.Decimal
,然后在其上调用静态
TryParse(string,out x)
方法

以下代码有两个问题:

  • t.GetMethod(“TryParse”,新类型[]{typeof(string),t})
    无法返回我期望的MethodInfo

  • mi.Invoke(null,新对象[]{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;
}
公共静态对象强制转换(对象值,字符串类型)
{
类型t=Type.GetType(类型);
如果(t!=null)
{
object-concreteInstance=Activator.CreateInstance(t);
十进制tempInstance=0;
LISTL=新列表(t.GetMethods(BindingFlags.Static | BindingFlags.Public));
MethodInfo-mi;
mi=t.GetMethod(“TryParse”,新类型[]{typeof(string),t});//这无法获取方法,返回null
mi=l.FirstOrDefault(x=>x.Name==“TryParse”&&x.GetParameters().Length==2);//由于前一行失败,需要进行难看的破解
如果(mi!=null)
{
尝试
{
bool-retVal=decimal.TryParse(value.ToString(),out-tempInstance);
Console.WriteLine(retVal.ToString());//retVal为true,tempInstance设置正确
对象z=mi.Invoke(null,新对象[]{value.ToString(),concreteInstance});
Console.WriteLine(z.ToString());//z为true,但未设置concreteInstance
}
捕获(例外情况除外)
{
Debug.WriteLine(例如消息);
}
}
返回具体实例;
}
返回值;
}
我需要做什么来确保我的
t.GetMethod()
调用返回正确的MethodInfo?我需要做什么才能在我的
mi.Invoke()
call中正确设置
concreteInstance


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

您需要使用正确的
绑定标志
并使用
类型。对于
out
ref
参数,使用MakeByRefType
。等一下,我会给你一个代码示例

比如说,

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
是因为我们正在调用一个静态方法(没有对象“接收”这个调用)。
TryParse
将使用解析结果为我们“填充”
inputParameters
中的
null
(它是
out
参数)