C#和#x27;找不到';现有方法

C#和#x27;找不到';现有方法,c#,.net,reflection,assemblies,runtime,C#,.net,Reflection,Assemblies,Runtime,你好! 我一直在(有点)玩弄C#及其组件。所以我发现了一个非常有趣的特性,比如动态加载程序集并调用其类成员。一点谷歌,我在这里,写一些“汇编浏览器”。(我使用了来自和的部分代码,但没有一个给出任何预期结果) 但我发现了一个小错误:当我试图从我加载的程序集中调用类方法时,应用程序引发了MissingMethod异常。我确信我正在加载的DLL包含我试图调用的类和方法(我的应用程序确保了我和RedGate的.NET反射程序一样): 主应用程序代码似乎是好的,我开始思考,如果我是我的DLL错误。。。啊

你好! 我一直在(有点)玩弄C#及其组件。所以我发现了一个非常有趣的特性,比如动态加载程序集并调用其类成员。一点谷歌,我在这里,写一些“汇编浏览器”。(我使用了来自和的部分代码,但没有一个给出任何预期结果)

但我发现了一个小错误:当我试图从我加载的程序集中调用类方法时,应用程序引发了MissingMethod异常。我确信我正在加载的DLL包含我试图调用的类和方法(我的应用程序确保了我和RedGate的.NET反射程序一样):

主应用程序代码似乎是好的,我开始思考,如果我是我的DLL错误。。。啊,我已经把两个项目放在一个解决方案中,但我认为这不会引起任何麻烦。是的,DLL项目有“类库”目标,而主应用程序有“控制台应用程序”目标

所以,问题是:他们怎么了

以下是一些源代码:

DLL源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public void Main()
        {
            System.Console.WriteLine("Hello, World!");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFrom(@"a\long\long\path\ClassLibrary1.dll");

            try
            {
                foreach (Type t in asm.GetTypes())
                {
                    if (t.IsClass == true && t.FullName.EndsWith(".Class1"))
                    {
                        object obj = Activator.CreateInstance(t);
                        object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); // Exception is risen from here
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Error: {0}", e.Message);
            }

            System.Console.ReadKey();
        }
    }
}
public class Class1
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
    }
}
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
主要应用程序来源:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public void Main()
        {
            System.Console.WriteLine("Hello, World!");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFrom(@"a\long\long\path\ClassLibrary1.dll");

            try
            {
                foreach (Type t in asm.GetTypes())
                {
                    if (t.IsClass == true && t.FullName.EndsWith(".Class1"))
                    {
                        object obj = Activator.CreateInstance(t);
                        object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); // Exception is risen from here
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Error: {0}", e.Message);
            }

            System.Console.ReadKey();
        }
    }
}
public class Class1
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
    }
}
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
UPD:只适用于一种情况-当DLL方法不带参数时:

DLL类(如果方法不是静态的,也可以使用):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public void Main()
        {
            System.Console.WriteLine("Hello, World!");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFrom(@"a\long\long\path\ClassLibrary1.dll");

            try
            {
                foreach (Type t in asm.GetTypes())
                {
                    if (t.IsClass == true && t.FullName.EndsWith(".Class1"))
                    {
                        object obj = Activator.CreateInstance(t);
                        object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); // Exception is risen from here
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Error: {0}", e.Message);
            }

            System.Console.ReadKey();
        }
    }
}
public class Class1
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
    }
}
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
方法调用代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public void Main()
        {
            System.Console.WriteLine("Hello, World!");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFrom(@"a\long\long\path\ClassLibrary1.dll");

            try
            {
                foreach (Type t in asm.GetTypes())
                {
                    if (t.IsClass == true && t.FullName.EndsWith(".Class1"))
                    {
                        object obj = Activator.CreateInstance(t);
                        object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); // Exception is risen from here
                    }
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Error: {0}", e.Message);
            }

            System.Console.ReadKey();
        }
    }
}
public class Class1
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
    }
}
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);

为了调用静态方法,为什么要对实例(
Activator.CreateInstance(t)
)进行装箱????应该是:

t.InvokeMember(
     "Main", 
     BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, 
     null, 
     null, 
     new object[] { new string[0] }
);
此外,定义的此方法不返回任何值,因此无需为其分配返回变量


为了消除所有误解,我在这里创建了一个完整的工作演示:

InvokeMember的最后一个参数是一个包含方法参数的对象数组


如果传递的是
null
,则应该传递一个包含单个元素的对象数组(字符串数组)。

可能是InvokeMember()参数错误。以下是一个有效的示例:

using System;
using System.Reflection;

class Program {
    static void Main(string[] args) {
        if (args.Length > 0) Console.WriteLine(args[0]);
        else {
            Assembly asm = Assembly.LoadFrom(Assembly.GetEntryAssembly().Location);
            foreach (Type t in asm.GetTypes()) {
                if (t.IsClass == true && t.FullName.EndsWith(".Program")) {
                    //object obj = Activator.CreateInstance(t);
                    object res = t.InvokeMember("Main",
                        BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,
                        null, null,
                        new object[] { new string[] { "Invoked" } });
                }
            }
        }
    }
}
  • 注意Main()方法如何不是公共的,因此BindingFlags.NonPublic
  • 注意Main()方法是静态的,因此BindingFlags.static
  • 出于同样的原因,为目标参数传递null
  • 出于同样的原因,CreateInstance也不是必需的
  • 注意Main()方法是如何接受string[]参数的,您必须传递它以获得反射以找到正确的方法重载
对于Main()方法,请遵循相同的逻辑:


我必须检查一下自己:你能通过调用一个对象来调用一个静态方法吗?看看下面的注释-有没有“static”、参数或其他什么都没有区别。不是静态的,也不是普通的方法都没有给出任何结果。同样的例外。另外,请注意,询问者没有为该方法提供任何参数。@shybovycha,从我所看到的
Class1.Main
是一个静态方法。您是否注意到我传递给
InvokeMember
调用的最后一个参数:
new object[]{new string[0]}
而不是
null
;如果是静态的一或否-结果保持不变-异常正在上升。@shybovycha:如果即使你做得很好,异常仍然发生,为什么不在原始问题中发布“正确”的代码?事实上,我们不知道你是否真正正确地尝试了它,或者你是否只是认为你用了“正确”的方式尝试了它,但是你错过了一些其他的错误。是的,谢谢!将字符串数组作为参数列表传递时出错(请参阅InvokeMember()。非常感谢!=)哦,对不起,我错过了你文章的最后两行=(