C#和#x27;找不到';现有方法
你好! 我一直在(有点)玩弄C#及其组件。所以我发现了一个非常有趣的特性,比如动态加载程序集并调用其类成员。一点谷歌,我在这里,写一些“汇编浏览器”。(我使用了来自和的部分代码,但没有一个给出任何预期结果) 但我发现了一个小错误:当我试图从我加载的程序集中调用类方法时,应用程序引发了MissingMethod异常。我确信我正在加载的DLL包含我试图调用的类和方法(我的应用程序确保了我和RedGate的.NET反射程序一样): 主应用程序代码似乎是好的,我开始思考,如果我是我的DLL错误。。。啊,我已经把两个项目放在一个解决方案中,但我认为这不会引起任何麻烦。是的,DLL项目有“类库”目标,而主应用程序有“控制台应用程序”目标 所以,问题是:他们怎么了 以下是一些源代码: DLL源代码:C#和#x27;找不到';现有方法,c#,.net,reflection,assemblies,runtime,C#,.net,Reflection,Assemblies,Runtime,你好! 我一直在(有点)玩弄C#及其组件。所以我发现了一个非常有趣的特性,比如动态加载程序集并调用其类成员。一点谷歌,我在这里,写一些“汇编浏览器”。(我使用了来自和的部分代码,但没有一个给出任何预期结果) 但我发现了一个小错误:当我试图从我加载的程序集中调用类方法时,应用程序引发了MissingMethod异常。我确信我正在加载的DLL包含我试图调用的类和方法(我的应用程序确保了我和RedGate的.NET反射程序一样): 主应用程序代码似乎是好的,我开始思考,如果我是我的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[]参数的,您必须传递它以获得反射以找到正确的方法重载
我必须检查一下自己:你能通过调用一个对象来调用一个静态方法吗?看看下面的注释-有没有“static”、参数或其他什么都没有区别。不是静态的,也不是普通的方法都没有给出任何结果。同样的例外。另外,请注意,询问者没有为该方法提供任何参数。@shybovycha,从我所看到的
Class1.Main
是一个静态方法。您是否注意到我传递给InvokeMember
调用的最后一个参数:new object[]{new string[0]}
而不是null
;如果是静态的一或否-结果保持不变-异常正在上升。@shybovycha:如果即使你做得很好,异常仍然发生,为什么不在原始问题中发布“正确”的代码?事实上,我们不知道你是否真正正确地尝试了它,或者你是否只是认为你用了“正确”的方式尝试了它,但是你错过了一些其他的错误。是的,谢谢!将字符串数组作为参数列表传递时出错(请参阅InvokeMember()。非常感谢!=)哦,对不起,我错过了你文章的最后两行=(