如何使用反射调用带有 ref/out 参数的方法

问题描述 投票:0回答:2

想象我有以下课程:

class Cow {
    public static bool TryParse(string s, out Cow cow) {
        ...
    }
}

是否可以通过反射调用

TryParse
?我知道基础知识:

var type = typeof(Cow);
var tryParse = type.GetMethod("TryParse");

var toParse = "...";

var result = (bool)tryParse.Invoke(null, /* what are the args? */);
c# .net reflection
2个回答
8
投票

你可以这样做:

static void Main(string[] args)
{
    var method = typeof (Cow).GetMethod("TryParse");
    var cow = new Cow();           
    var inputParams = new object[] {"cow string", cow};
    method.Invoke(null, inputParams); 
    // out parameter value is then set in inputParams[1]
    Console.WriteLine( inputParams[1] == null ); // outputs True
}

class Cow
{
    public static bool TryParse(string s, out Cow cow) 
    {
        cow = null; 
        Console.WriteLine("TryParse is called!");
        return false; 
    }
}

0
投票

抱歉打扰了,但是这个帖子之前的答案让我开始了,但没有完全回答我所需要的。这是我找到的其余答案:

使用反射时,

in
out
ref
方法参数类型都是同一种特殊的“ref”类型,您可以通过执行
typeof(MyType).MakeByRefType()
获得。 搜索参数类型匹配的方法时,
MyType
ref MyType
被认为不相等!

下面的代码是我向我的类添加 TryParse 方法,该类包含通用结构

TData
。我的 TryParse 反射式搜索
TData
的 TryParse 并尝试调用它,而不必为每个持有的
TData
结构类型手动实现 TryParse 重写方法。

(尝试;捕获;为了便于阅读,删除了其他一些内容)

public bool TryParse(string stringToParse, out TData outResult)
{
    // Given 'TData' is the type we want to try to invoke TryParse() on...
    const string METHOD_NAME = "TryParse";
    Type type = typeof(TData);
    Type[] methodParams = new[] { typeof(string), type.MakeByRefType() }; //GetMethod() will fail without MakeByRefType() here!
    MethodInfo method = type.GetMethod(METHOD_NAME, BindingFlags.Static | BindingFlags.Public, null, methodParams, null);

    TData outResult = default(TData);
    if (method == null) 
        return false;

    // TryParse "out TData" gets written to object[1] array after invoke.
    object[] invokeParams = new object[] { stringToParse, outResult };
    object result = method.Invoke(null, invokeParams);

    if (result is bool didParse && didParse)
    {
        outResult = (TData)invokeParams[1]; //Read what the method wrote as "out TData"
        return true; // return parse success
    }
    return false;
}
© www.soinside.com 2019 - 2024. All rights reserved.