2009-09-16 9 views
5

リフレクションを使用して実行時にオブジェクトを見つけることができるのだろうか?これは実用的な要件よりも多くの実験です。C#Reflection:実行時にオブジェクトのインスタンスを見つけることは可能ですか?

オブジェクトインスタンスに対して.GetType()メソッドを使用しましたが、オブジェクトに対してさまざまなことを実行しましたが、私の質問は、実行時に特定の型のオブジェクトが存在することがわかっていますが、それを名前で参照してください。

さらに具体的な例として、DLLを読み込むWinFormsアプリケーションがあるとします。そのDLLは、フォームとのやり取りやパブリックメソッドの呼び出しのためにフォームオブジェクトへの参照を個別に見つける方法を教えてください。

これも可能ですか?

答えて

7

いいえ、基本的には、

あなたはタイプから "興味のあるタイプのインスタンス"までの恐ろしいグローバルマップを持つことができますが、そうでなければいいえ。

基本的にWinFormsアプリケーションは、フォームへの参照を何とかDLLに渡す必要があります。

1

これはできません。これは、Microsoftによって個人的に実装されているため、C/C++に比べてポインタではなく、古いC/C++ではメモリをスキャンできますが、.NETではそうしたツールはありません。

0

私はあなたの質問を理解しませんでした。オブジェクトを参照するときは、オブジェクト・インスタンスを検索しているのか、オブジェクト・タイプを検索しているのですか?

インスタンスを探している場合、答えはいいえです。実行時に名前で型を検索する場合、答えは「はい」です。

次の行は、AppDomain内のすべての読み込まれたアセンブリを取得するのを許可します。 AppDomain.CurrentDomain.GetAssemblies();

インスタンスメソッドAssembly.GetTypes()は、アセンブリ内のすべての型を取得します。

編集:タイプの名前を知っていたのを忘れてしまった。 Assembly.GetType(string name)を使用することもできます。

0

アプリケーションのためのプラグインフレームワークを設計できます。 はここに例を示します

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:ところで私の知る限りでは、あなたの質問への答えは、他の人が既に答えてきたように何が

0

、いや、それは一般的な方法では不可能ではありません。

ただし、より具体的なシナリオでは、Win APIからすべてのWindowsの一覧を取得して、それぞれを検索しようとしているプロパティについて調べることができます。

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; 
    } 
} 
+0

*周りの長い道のりを使用しています。 'Application'オブジェクトはすべてのものを' OpenForms'コレクション(WinFormsアプリケーション用)に保持します。 –

0

あなただけの実験を、あなたが行うことができ、あなたの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; 

はちょうどその依存assemblysのためではなく、動的にロードされたもののためにテストしました。しかし、それは試してみる価値があるかもしれません。

特定のインスタンスを見つける一般的な問題については、質問はすでに回答済みです。

0

Jon Skeetは正当なものであり、任意のタイプでは不可能です。

具体的な例としては、可能です。そして、あなたは、pする必要はありません/ EnumWindowsを呼び出すか、本当に*ですForm.FromHandle()

Form f = Application.OpenForms.Where(x => x.GetType().Name == "FormIWant").FirstOrDefault(); 
関連する問題