如何调用一个带有输出参数的方法?

49

我想暴露WebClient.DownloadDataInternal方法,像下面这样:

[ComVisible(true)]
public class MyWebClient : WebClient
{
    private MethodInfo _DownloadDataInternal;

    public MyWebClient()
    {
        _DownloadDataInternal = typeof(WebClient).GetMethod("DownloadDataInternal", BindingFlags.NonPublic | BindingFlags.Instance);
    }

    public byte[] DownloadDataInternal(Uri address, out WebRequest request)
    {
        _DownloadDataInternal.Invoke(this, new object[] { address, out request });
    }

}

WebClient.DownloadDataInternal有一个输出(out)参数,我不知道如何调用它。 求助!

2个回答

129
您可以像调用其他方法一样通过反射调用带有out参数的方法。不同之处在于返回值将复制回参数数组,以便您可以从调用函数中访问它。
object[] args = new object[] { address, request };
_DownloadDataInternal.Invoke(this, args);
request = (WebRequest)args[1];

第一行无法被编译。 - ldp615
如果有另一个重载的方法会发生什么情况呢?例如:int test(int i, out string s) { s = ""; return 0; }int test(int i) { return 0; } - MrClan
9
如果你正在使用需要传递类型参数的 Invoke 版本,那么请确保对于输出参数使用 Type.MakeByRefType 实例方法。(这里不相关,但在我的情况下是需要的!) - Kenneth K.
1
你可以首先在该类型中选择重载(使用Type :: GetMethods等),然后从其MethodInfo :: Invoke中调用特定的方法。这样可以避免重载、参数类型列表等问题。此外,你可以将方法分辨错误与调用错误分开--当有什么问题时非常好用。 - hypersw

23
public class MyWebClient : WebClient
{
    delegate byte[] DownloadDataInternal(Uri address, out WebRequest request);

    DownloadDataInternal downloadDataInternal;

    public MyWebClient()
    {
        downloadDataInternal = (DownloadDataInternal)Delegate.CreateDelegate(
            typeof(DownloadDataInternal),
            this,
            typeof(WebClient).GetMethod(
                "DownloadDataInternal",
                BindingFlags.NonPublic | BindingFlags.Instance));
    }

    public byte[] DownloadDataInternal(Uri address, out WebRequest request)
    {
        return downloadDataInternal(address, out request);
    }
}

@JaredPar的语法糖为基本解决方案。清晰易懂,有助于提高可读性和测试。+1 - IAbstract

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接