【问题标题】:Pass delegate with reflection通过反射传递委托
【发布时间】:2013-07-12 14:01:38
【问题描述】:

我有一个类,它有一个采用委托参数的方法,它可以通过反射来调用,例如:

namespace NSa
{
    public delegate void dlg(string p1, string p2);

    public class dyn
    {
        void method(dlg d)
        {
            // call d...
        }
    }
}

在另一个类中,我需要通过反射调用dyn.method

namespace NSa
{
    public delegate void dlg(string p1, string p2);

    public void fun(string a, string b) { Console.Write(a); }

    public class other
    {
        void caller_method()
        {
            dlg x = fun;

            //... 

            var assembly = System.Reflection.Assembly.LoadFile("xx.dll");
            System.Reflection.BindingFlags flags = (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
            System.Reflection.Module[] dynModules = assembly.GetModules();
            Type dynType = dynModules[0].GetType("NSa.dyn");
            object dynObj = Activator.CreateInstance(dynType);               
            System.Reflection.MethodInfo dynMethod = dynType.GetMethods(flags).Where(m => m.Name == "method").First();
            dynMethod.Invoke(dynObj, new object[] {x});             
        }
    }
}

我得到异常:

Object of type 'NSa.dlg' cannot be converted to type 'NSa.dlg'.

我错过了什么?

【问题讨论】:

  • 对未来问题的一点建议 - 如果代码遵循相关语言的正常命名约定,避免缩写,并使用 using 指令而不是完全限定每个输入名称。

标签: c# reflection delegates


【解决方案1】:

看起来您在两个不同的程序集中两次声明了相同的类型。就 CLR 而言,这将是两种完全不同的类型,它们之间没有转换。

您应该使用在与dyn 相同的程序集中声明的委托,以便将其传递给dyn.method。如果您在编译时不知道该程序集,则需要使用 Delegate.CreateDelegate 创建该方法的实例。

我还建议,通过对不同的程序集使用不同的命名空间声明,可以更容易分辨出哪个类型来自哪个程序集。

【讨论】:

  • 对。如何在第一个程序集中创建一个委托类型的实例,该实例指向调用程序程序集中的函数(在示例中很有趣)?
  • @paulsimmons:正如我所说,您使用Delegate.CreateDelegate,传入MethodInfo 和目标引用。我举个例子,但你当前的代码甚至不会编译,因为 fun 不在类型中......
  • 哎呀,我在编辑之前没有看到,谢谢!它解决了我的问题。
猜你喜欢
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多