【问题标题】:How to use Reflection to Invoke an Overloaded Method in .NET如何使用反射在 .NET 中调用重载方法
【发布时间】:2010-09-18 10:03:52
【问题描述】:

有没有办法在 .NET (2.0) 中使用反射来调用重载方法。我有一个应用程序可以动态实例化从公共基类派生的类。出于兼容性目的,此基类包含 2 个同名方法,一个带参数,一个不带参数。我需要通过 Invoke 方法调用无参数方法。现在,我得到的只是一个错误,告诉我我正在尝试调用一个模棱两可的方法。

是的,我可以将对象转换为我的基类的实例并调用我需要的方法。最终发生,但现在,内部复杂性不允许它发生。

任何帮助都会很棒!谢谢。

【问题讨论】:

    标签: .net reflection .net-2.0 invoke overloading


    【解决方案1】:

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

    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]);
    

    【讨论】:

    • 你也可以做Type.EmptyTypes
    • 需要 } 在 "typeof(int), typeof(string)" 之后编译:)
    • 如果其中一个参数是通用的怎么办?
    • 当你有一个对象实例时,你就知道它被实例化了哪些类型。
    • 如果你需要指定一个输出参数,不要乱用修饰符,这不起作用(对我来说)。您需要传递类型对象并将其 IsByRef 属性设置为 true。虽然 IsByRef 是只读的,但您需要使用类型的 MakeByRefType 方法将类型转换为具有此属性集的实例。
    【解决方案2】:

    是的。当您调用该方法时,传递与您想要的重载匹配的参数。

    例如:

    Type tp = myInstance.GetType();
    
    //call parameter-free overload
    tp.InvokeMember( "methodName", BindingFlags.InvokeMethod, 
       Type.DefaultBinder, myInstance, new object[0] );
    
    //call parameter-ed overload
    tp.InvokeMember( "methodName", BindingFlags.InvokeMethod, 
       Type.DefaultBinder, myInstance, new { param1, param2 } );
    

    如果您以相反的方式执行此操作(即通过查找 MemberInfo 并调用 Invoke),请小心您得到正确的 - 无参数重载可能是第一个找到的。

    【讨论】:

    • 有趣的是,这不起作用。我没有向我的无参数方法传递任何参数,但我仍然得到一个模棱两可的调用。
    • 如何处理不同类型的参数?假设我有两个重载,一个采用字符串,另一个采用 int?
    • 没问题 - 参数的基础类型是检查的内容。
    • 要小心的是,当您的类型隐式转换为彼此时,.Net 会选择实例方法而不是继承方法。
    • 查看这个问题的例子:stackoverflow.com/questions/154112
    【解决方案3】:

    使用带有 System.Type[] 的 GetMethod 重载,并传递一个空的 Type[];

    typeof ( Class ).GetMethod ( "Method", new Type [ 0 ] { } ).Invoke ( instance, null );
    

    【讨论】:

    • 你可以使用 Type.EmptyTypes
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多