C#反思:是否有可能在执行期间对象的实例?(C# Reflection: Is it possibl

2019-07-18 06:03发布

我不知道是否有可能使用反射来定位在运行时的对象? 这更多的是一种实验比实际需要的。

我用.GetType()方法的对象实例做各种事情的对象,但我的问题是:如果我知道存在于运行某种类型的对象,但我不能引用它名称。

作为一个更具体的例子,假设我有一个WinForms应用程序,加载DLL - 怎么可能是DLL独立,以便与表单交互,或者叫公共方法定位到窗体对象的引用?

这甚至可能吗?

Answer 1:

没有,基本上是这样。

你可能有某种类型从全球恐怖地图以“我感兴趣的类型的实例在”但除此之外,没有。

基本上,WinForms应用程序应传递到的形式的参考到DLL不知。



Answer 2:

都能跟得上,这是不可能的,因为引用由微软私下实现他们并不比C / C ++的指针,在旧的C / C ++,你可以扫描你的内存,但在.NET中有没有这样的工具。



Answer 3:

我不明白你的问题。 当你引用一个对象,你的意思是你正在寻找一个对象实例,或者你指的是搜索对象类型?

如果你正在寻找一个实例,那么答案是否定的。 如果你在运行时寻找一个类型的名称,那么答案是肯定的。

下面一行将让你得到所有的AppDomain中加载的程序集:AppDomain.CurrentDomain.GetAssemblies();

实例方法Assembly.GetTypes()将让你在一个程序集中的所有类型。

编辑:忘记你知道类型的名称。 您还可以使用Assembly.GetType(string name)



Answer 4:

你可以设计为您的应用插件框架。 下面是一个例子:

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,据我所知回答你的问题是没有



Answer 5:

正如其他人已经回答了,没有,它是不可能在一般的方式。

但是,对于更具体的场景中,你可以得到从运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;
    }
}


Answer 6:

如果你只是尝试,并试图从你的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。



Answer 7:

乔恩斯基特是正确的,这是不可能的只是任意类型。

为了您的具体的例子,它是可能的。 而你并不需要的P / Invoke EnumWindows或使用Form.FromHandle()

Form f = Application.OpenForms.Where(x => x.GetType().Name == "FormIWant").FirstOrDefault();


文章来源: C# Reflection: Is it possible to find an instance of an object at runtime?
标签: c# reflection