【问题标题】:HOW TO get an overloaded private/protected method using reflection如何使用反射获得重载的私有/受保护方法
【发布时间】:2016-10-24 17:34:30
【问题描述】:
using System;
using System.Reflection;

namespace Reflection        
{
    class Test
    {
        protected void methodname(int i)
        {
            Console.WriteLine(("in the world of the reflection- only i"));
            Console.Read();
        }    
        protected void methodname(int i, int j)
        {
            Console.WriteLine(("in the world of the reflection  i , j"));
            Console.Read();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
           // BindingFlags eFlags = BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public|BindingFlags.NonPublic;
            BindingFlags eFlags = BindingFlags.Instance|BindingFlags.NonPublic;
            Test aTest = new Test();
            MethodInfo mInfoMethod = typeof(Reflection.Test).GetMethod("methodname", eFlags);
            mInfoMethod.Invoke(aTest, new object[] { 10 ,20});   
        }
    }
}

我想调用两个 Getmethod() 重载方法。如果我给出方法名称,则会引发运行时错误(不明确的方法调用)。如何避免这种情况以及如何调用每个方法。

【问题讨论】:

  • 你不能用一个 Invoke() 调用来调用两个重载。你必须分别Invoke()每一个。
  • 如何分别调用各个方法?
  • 只打两次Invoke()

标签: c# reflection


【解决方案1】:

您必须传递重载方法的类型,这就是在重载时反射如何整理出您想要的方法的方式。

您不能同时调用这两种方法,因为它具有不同类型的输入参数。你必须确切地知道你到底想打电话给哪一个,并传递一个Type[],例如:

// invoking overload with two parameters
MethodInfo mInfoMethod =
    typeof(Reflection.Test).GetMethod(
        "methodname",
        BindingFlags.Instance | BindingFlags.NonPublic,
        Type.DefaultBinder,
        new[] {typeof (int), typeof (int)},
        null);

mInfoMethod.Invoke(aTest, new object[] { 10 ,20});

// invoking overload with one parameters
MethodInfo mInfoMethod =
    typeof(Reflection.Test).GetMethod(
        "methodname",
        vBindingFlags.Instance | BindingFlags.NonPublic,
        Type.DefaultBinder,
        new[] { typeof (int) },
        null);

mInfoMethod.Invoke(aTest, new object[] { 10 });

【讨论】:

  • 尝试了建议的方法:意图调用接受两个参数的重载方法。但是getmethod()返回空值。
  • 好吧,你不能调用受保护的方法,考虑把它公开
  • 我已更新代码以使用反射调用受保护的方法。请立即查看
【解决方案2】:

使用“GetMethods”来检索所有重载,然后选择你想要的。

【讨论】:

  • 例如,GetMethods 不检索继承的受保护方法。
  • 通过设置正确的 BindingFlags 来实现:type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic))
【解决方案3】:

请在下面找到一个工作示例:

public class ReflectionSample
    {
        protected void Method(int i)
        {
            Console.WriteLine(string.Format("in the world of the reflection- only {0}", i));
            Console.Read();
        }
        protected void Method(int i, int j)
        {
            Console.WriteLine(string.Format("in the world of the reflection  {0} , {1}", i,j));
            Console.Read();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var eFlags = BindingFlags.Instance | BindingFlags.NonPublic;
            var objType = Type.GetType("Sample.ReflectionSample");
            var methods = objType.GetMethods(eFlags);
            foreach (var method in methods)
            {
                if (method.Name == "Method")
                {
                    Console.WriteLine("Method name is :" + method.Name);
                    var parameters = method.GetParameters();
                    int value = 10;
                    List<object> param = new List<object>();
                    for (int i = 0; i < parameters.Count(); i++)
                    {
                        param.Add(value * 5);
                    }
                    Console.WriteLine(parameters.Count());
                    method.Invoke(new ReflectionSample(), param.ToArray());
                }
            }
        }
    }

【讨论】:

  • 刚刚在 method.Name 上添加了 if 条件以过滤它以仅调用所需的方法。
  • 我尝试了示例应用程序,Getmethods 抛出异常
  • 我刚刚开始工作,然后发布了示例。你能告诉我它抛出的异常是什么吗?还要确保您的项目构建属性具有 .NET 4.0 作为框架,而不是 .NET 4.0 客户端配置文件。还要在管理员权限下运行 Vs.Net。您使用的是哪个版本的 .Net?
  • 另请注意,ReflectionSample 类的命名空间是“Sample”,因此 GetMethods 具有类的完整路径 --> Namespace.ClassName
  • 我使用的是 3.5 .net 版本,我得到了异常对象:NullReferenceException 未处理。 {"对象引用未设置为对象的实例。"}
【解决方案4】:

你可以这样试试吗

你必须指定你想要的方法:

class SomeType 
{
    void Foo(int size, string bar) { }
    void Foo() { }
}

SomeType obj = new SomeType();
// call with int and string arguments
obj.GetType().GetMethod("Foo", new Type[] { typeof(int), typeof(string)).Invoke(obj, new object[] { 42, "Hello" });
// call without arguments
obj.GetType().GetMethod("Foo", new Type[0]).Invoke(obj, new object[0]);

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 2014-09-21
    • 2012-01-11
    • 2011-09-20
    • 1970-01-01
    • 2012-01-09
    • 2013-01-18
    • 2012-01-22
    相关资源
    最近更新 更多