C#“找不到”现有方法
问候! 我一直在(有点)闲逛 C# 及其程序集。因此,我发现了一个有趣的功能,例如动态加载程序集并调用其类成员。谷歌了一下,我在这里写了某种“程序集浏览器”。 (我使用了 此处、此处 和 这里并且没有一个给出任何预期的结果)。
但我发现了一个小错误:当我尝试从已加载的程序集中调用类方法时,应用程序引发了 MissingMethod 异常。我确信我正在加载的 DLL 包含我尝试调用的类和方法(我的应用程序确保我以及 RedGate 的 .NET Reflector 一样):
主要应用程序代码似乎没问题,我开始思考我的 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();
}
}
}
UPD: 适用于一种情况 - 当 DLL 方法不带参数时:
DLL 类(如果方法不是静态的也适用):
public class Class1
{
public static void Main()
{
System.Console.WriteLine("Hello, World!");
}
}
方法调用代码:
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
Greetings!
I've been fooling around (a bit) with C# and its assemblies. And so i've found such an interesting feature as dynamic loading assemblies and invoking its class members. A bit of google and here i am, writing some kind of 'assembly explorer'. (i've used some portions of code from here, here and here and none of 'em gave any of expected results).
But i've found a small bug: when i tried to invoke class method from assembly i've loaded, application raised MissingMethod exception. I'm sure DLL i'm loading contains class and method i'm tryin' to invoke (my app ensures me as well as RedGate's .NET Reflector):
The main application code seems to be okay and i start thinking if i was wrong with my DLL... Ah, and i've put both of projects into one solution, but i don't think it may cause any troubles. And yes, DLL project has 'class library' target while the main application one has 'console applcation' target.
So, the question is: what's wrong with 'em?
Here are some source code:
DLL source:
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!");
}
}
}
Main application source:
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();
}
}
}
UPD: worked for one case - when DLL method takes no arguments:
DLL class (also works if method is not static):
public class Class1
{
public static void Main()
{
System.Console.WriteLine("Hello, World!");
}
}
Method invoke code:
object res = t.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能会弄错 InvokeMember() 参数。下面是一个有效的示例:
对 Main() 方法遵循相同的逻辑:
You are likely getting the InvokeMember() arguments wrong. Here's a sample that works:
Follow the same logic for your Main() method:
为什么要创建一个实例(
Activator.CreateInstance(t)
)来调用静态方法???它应该是:此外,定义的这个方法不返回任何值,因此不需要为其分配返回变量。
为了消除所有误解,我在这里创建了一个完整的工作演示: http://www.mediafire.com /?n7h9b8ghomfv17d
Why are you craeting an instance (
Activator.CreateInstance(t)
) in order to invoke a static method???? It should be:Also this method as defined doesn't return any value so no need to assign it a return variable.
And in order to clear all misunderstandings I've created a full working demo here: http://www.mediafire.com/?n7h9b8ghomfv17d
InvokeMember
的最后一个参数是包含该方法参数的对象数组。您在那里传递
null
,您应该传递包含单个元素(字符串数组)的对象数组。The last parameter to
InvokeMember
is an array of Objects containing the arguments to the method.You're passing
null
there, you should be passing an array of objects containing a single element (an array of strings).