如何通过 反射 调用某个对象的私有方法?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过 反射 调用某个对象的私有方法?相关的知识,希望对你有一定的参考价值。

咨询区

  • Jeromy Irvine

我的类中有一组私有方法,我现在想根据灵活的输入值来动态调用其中的私有方法,代码类似是这个样子。

MethodInfo dynMethod = this.GetType().GetMethod("Draw_" + itemType);
dynMethod.Invoke(this, new object[]  methodParams );

代码跑起来后,我发现 dynMethod 并没有返回结果,请问我该如何配置才能正确的返回?

回答区

  • cod3monk3y

如果你真的想解决这个问题,个人建议你写个扩展方法,比如下面这样。

static class AccessExtensions

    public static object call(this object o, string methodName, params object[] args)
    
        var mi = o.GetType ().GetMethod (methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance );
        if (mi != null) 
            return mi.Invoke (o, args);
        
        return null;
    

然后可以这样使用

class Counter
    
        public int count  get; private set; 
        void incr(int value)  count += value; 
    

    [Test]
    public void making_questionable_life_choices()
    
        Counter c = new Counter ();
        c.call ("incr", 2);             // "incr" is private !
        c.call ("incr", 3);
        Assert.AreEqual (5, c.count);
    
  • Owen James

微软最近修改了 反射API,在新的反射模式和平台下,大概是这么写的。

obj.GetType().GetTypeInfo().GetDeclaredMethod("MethodName").Invoke(obj, yourArgsHere);

实践中最好还是封装成一个泛型方法,比如下面这样。

public static object InvokeMethod<T>(this T obj, string methodName, params object[] args)

    var type = typeof(T);
    var method = type.GetTypeInfo().GetDeclaredMethod(methodName);
    return method.Invoke(obj, args);

注意:

  1. 如果你需要调用的方法是在 obj 的基类中,那这里的泛型参数 T 要显式定义为基类。

  2. 如果你需要调用的方法是一个异步方法, 你可以使用 await (Task) obj.InvokeMethod(…)

点评区

确实微软已经优化了各种 反射Api,使用起来虽然较慢,但相比以前要好很多了。

以上是关于如何通过 反射 调用某个对象的私有方法?的主要内容,如果未能解决你的问题,请参考以下文章

Java之反射 — 用法及原理

JDK源码(十三):Class

PHP通过反射方法调用执行类中的私有方法

java反射的理解

java反射机制可以调用到私有方法,是否就破坏了JAVA的卦装性呢。

Java面试题:如何通过反射获取和设置对象私有字段的值?