我不知道是否有可能使用反射来定位在运行时的对象? 这更多的是一种实验比实际需要的。
我用.GetType()方法的对象实例做各种事情的对象,但我的问题是:如果我知道存在于运行某种类型的对象,但我不能引用它名称。
作为一个更具体的例子,假设我有一个WinForms应用程序,加载DLL - 怎么可能是DLL独立,以便与表单交互,或者叫公共方法定位到窗体对象的引用?
这甚至可能吗?
我不知道是否有可能使用反射来定位在运行时的对象? 这更多的是一种实验比实际需要的。
我用.GetType()方法的对象实例做各种事情的对象,但我的问题是:如果我知道存在于运行某种类型的对象,但我不能引用它名称。
作为一个更具体的例子,假设我有一个WinForms应用程序,加载DLL - 怎么可能是DLL独立,以便与表单交互,或者叫公共方法定位到窗体对象的引用?
这甚至可能吗?
没有,基本上是这样。
你可能有某种类型从全球恐怖地图以“我感兴趣的类型的实例在”但除此之外,没有。
基本上,WinForms应用程序应传递到的形式的参考到DLL不知。
都能跟得上,这是不可能的,因为引用由微软私下实现他们并不比C / C ++的指针,在旧的C / C ++,你可以扫描你的内存,但在.NET中有没有这样的工具。
我不明白你的问题。 当你引用一个对象,你的意思是你正在寻找一个对象实例,或者你指的是搜索对象类型?
如果你正在寻找一个实例,那么答案是否定的。 如果你在运行时寻找一个类型的名称,那么答案是肯定的。
下面一行将让你得到所有的AppDomain中加载的程序集:AppDomain.CurrentDomain.GetAssemblies();
实例方法Assembly.GetTypes()
将让你在一个程序集中的所有类型。
编辑:忘记你知道类型的名称。 您还可以使用Assembly.GetType(string name)
。
你可以设计为您的应用插件框架。 下面是一个例子:
public interface IPlugin
{
void Load(Form mainForm); //Or you can have an interface for you main form that allows your plugin to work with your form.
}
那么当你在运行时加载程序集,你可以找到你的插件。
foreach(var type in assembly.GetTypes())
{
if(typeof(IPlugin).IsAssignableFrom(type))
var plugin=(IPlugin)Activator.CreateInstance(type);
plugin.Load(_mainForm);
}
Updatd:BTW,据我所知回答你的问题是没有
正如其他人已经回答了,没有,它是不可能在一般的方式。
但是,对于更具体的场景中,你可以得到从运API的所有窗口的列表,然后检查每一个你正在尝试寻求属性。
public static class Helper
{
public static IntPtr[] GetToplevelWindows()
{
List<IntPtr> windowList = new List<IntPtr>();
GCHandle handle = GCHandle.Alloc(windowList);
try
{
Helper.EnumWindows(Helper.EnumWindowsCallback, (IntPtr)handle);
}
finally
{
handle.Free();
}
return windowList.ToArray();
}
private delegate bool EnumWindowsCallBackDelegate(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsCallBackDelegate callback, IntPtr lParam);
private static bool EnumWindowsCallback(IntPtr hwnd, IntPtr lParam)
{
((List<IntPtr>)((GCHandle)lParam).Target).Add(hwnd);
return true;
}
}
如果你只是尝试,并试图从你的DLL,你可以做定位主要形式有:
//get the current process
System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
//get its main windows handle (only works, if the form is already created)
IntPtr hWnd = p.MainWindowHandle;
//locate the form by its native handle
System.Windows.Forms.Form f = System.Windows.Forms.Form.FromHandle(hWnd) as System.Windows.Forms.Form;
刚刚测试,对大会的依赖,而不是动态加载的。 但它可能是值得一试。
对于定位特定实例的一般性问题,该问题已经answerd。
乔恩斯基特是正确的,这是不可能的只是任意类型。
为了您的具体的例子,它是可能的。 而你并不需要的P / Invoke EnumWindows
或使用Form.FromHandle()
Form f = Application.OpenForms.Where(x => x.GetType().Name == "FormIWant").FirstOrDefault();