• ベストアンサー

InvokeMemberメソッドとは何をするメソッドでしょうか?

はじめまして、質問です。 C#のソースコードで、「Type.InvokeMember メソッド」というのを使っている箇所があるのですが、 これがいったい何をするメソッドなのかよく分かりません。 msdnのヘルプでは、 「指定したバインディング制約を使用し、指定した引数リストと照合して、指定したメンバを呼び出します。 」 と言っていますが、知識不足で理解できていません。 ネットで検索しても参考になりそうなものが引っかからない状況です。 実際に使用している箇所のソースコードは以下のような感じです。 private void axWebBrowser1_NavigateComplete2(object sender, AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e) { Object o = e.pDisp; Object oDocument = null; oDocument = o.GetType().InvokeMember("Document",BindingFlags.GetProperty,null,o,null); o.GetType().InvokeMember("Application",BindingFlags.GetProperty,null,oDocument,null); 中略 } ご存知の方がいらっしゃいましたら宜しくお願い致します。 何か参考になるURLや、このように調べるべきだなどのアドバイスなどもありましたら、 ぜひお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

InvokeMemberはリフレクションの機能の一つです。 ※参考:http://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%95%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3 インスタンスの型名が決まっていない状態で 文字列でメソッドを呼び出したりプロパティを呼び出したり、或いはインスタンスの生成を行う事ができます。 下記TestA、TestBというクラスがありDocumentという名前は同じですが 全く別のプロパティです。InvokeMemberを使えば 文字列として"Document"を与えることでそれぞれのプロパティを呼び出すことできます。 using System; using System.Reflection; class Program {   class TestA   {     public String Document     {       get { return "a"; }     }   }   class TestB   {     public String Document     {       get { return "b"; }     }   }   static void test(Object o)   {     String s = (String)o.GetType().InvokeMember("Document", BindingFlags.GetProperty, null, o, null);     System.Console.WriteLine(s);   }   static void Main(string[] args)   {     TestA a = new TestA();     TestB b = new TestB();     test(a);     test(b);   } } ■実行結果 a b

gawein193
質問者

お礼

ご回答ありがとうございます! そうですか、 > 文字列として"Document"を与えることでそれぞれのプロパティを呼び出すことできます。 ということなんですね。 参考URLもありがとうございました。 まだ未熟で検索してもうまくひっかからなくて困っていました。 サンプルもわかりやすくのせていただき助かりました。 ありがとうございます。

その他の回答 (1)

回答No.1

 こんにちは。  C#は知らないのですが、参考になりそうなリンクを張っておきます。  想像の領域ですがリンクを参考して考えると oDocument = o.GetType().InvokeMember("Document",BindingFlags.GetProperty,null,o,null); ↓ oDocument = o.Document;  という事でしょうか。

参考URL:
http://dobon.net/vb/dotnet/programing/typeinvokemember.html
gawein193
質問者

お礼

お返事が遅れてすみません。 URL、参考になりました。 ありがとうございました!

関連するQ&A

  • C# Wordファイルから文章データを取得

    いつもお世話になっております。 只今、Wordの中身をリッチテキストボックスに取得しようとしています。 取得したデータを他の形式に変更するので、中身を編集というのはしない予定です。 取り込むこと自体はできるようになりまして なんとかなるかなと思っていたのですが、動作を確認していると どうも大きなファイルだと上手くいかないのです。 十数ページなら何とかいけても、数十ページだとエラーが出ます。 そこで質問です。  1:考えられる原因にはどんなものがあるでしょうか     クリップボードを利用してるので、そこが怪しいですが     ほかにありましたらお願いします。  2:解決する方法にはどんなものがあるでしょうか?  3:この方法以外にWordのデータを取得する方法はあるでしょうか?   (クリップボードを利用する以外の方法) ソースは以下のように記述しました。 --------------------------------- Type wt = Type.GetTypeFromProgID("Word.Application"); Object wApp = Activator.CreateInstance(wt); try {     Object tmpDoc = wApp.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, wApp, null);     object[] tmpFile = {             fileName,             false,             true,             false,             Type.Missing,             Type.Missing,             true,             Type.Missing,             Type.Missing,             Type.Missing,             Type.Missing,             false,             true,             Type.Missing,             true,             Type.Missing            };     Object wDoc = tmpDoc.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, tmpDoc, tmpFile);     Object activeW = wDoc.GetType().InvokeMember("ActiveWindow", BindingFlags.GetProperty, null, wDoc, null);     Object activeWSelection = activeW.GetType().InvokeMember("Selection", BindingFlags.GetProperty, null, activeW, null);     activeWSelection.GetType().InvokeMember("WholeStory", BindingFlags.InvokeMethod, null, activeWSelection, null);     activeWSelection.GetType().InvokeMember("Copy", BindingFlags.InvokeMethod, null, activeWSelection, null);     //クリップボードの中身取得     IDataObject data = Clipboard.GetDataObject();     //リッチテキストボックス(rTextにデータを挿入)     rText.Rtf = data.GetData(DataFormats.Rtf).ToString(); } catch (Exception ex) {     MessageBox.Show(ex.ToString()); } finally {     Object apApp = wApp.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, wApp, null);     apApp.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, apApp, new object[] { Type.Missing, Type.Missing, Type.Missing }); } --------------------------------- あちこち参考サイトを見て回っているのですが 捜し方が悪いのか、クリップボードを利用する方法以外が見つかりません。 わかる方がいましたら、よろしくお願いします。 開発環境:VisualStudio2008 実行環境:Vista Word:*.doc/*.docx

  • C# Excelを遅延バインディングで操作する方法

    いつもお世話になっております 只今C#でExcelファイルを出力するプログラムを作成しています。 以前やり方が分からずここに質問し、なんとかExcelに出力できるようになったのですが Excelのバージョンが2007にしか対応していないことが分かり 遅延バインディング仕様に作り変えている最中です。 ところが、あと少しというところでクリアできない問題が2つ出てきたので、質問させていただきます。 1つは枠線を引く処理です。現在以下のように記述していますが どうしても例外が発生してしまいます(0x800A03EC) Type line = Type.GetTypeFromProgID("Excel.XlLineStyle.xlContinuous"); Type insidevertical = Type.GetTypeFromProgID("Excel.XlBordersIndex.xlInsideVertical"); Object tempA = objRange.GetType().InvokeMember("Borders", BindingFlags.GetProperty, null, objRange, null); Object tempB = tempA.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, tempA, new object[] { insidevertical }); tempB.GetType().InvokeMember("LineStyle", BindingFlags.SetProperty, null, tempB, new object[] { line }); これがどう解決していいかわかりません・・・ 遅延バインディングという手法も最近知ったばかりで、見よう見まねという状況です。 2つ目は、ファイル保存時の拡張子です。 現在は以下のように記述しています (問題なく動作はしてくれます) object[] mySave ={strFileName,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing}; objBook.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, objBook, mySave); 以前はこのようにしていました objBook.SaveAs(strFileName,      Excel.XlFileFormat.xlExcel8,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Excel.XlSaveAsAccessMode.xlNoChange,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing,      Type.Missing); 保存する拡張子をxlsに統一したいのですが、遅延にした場合のファイル形式の指定方法がわかりません Type.Missingにすると、実行環境にあるものに合わせた拡張子で保存されてしまい Excel2007を使用している環境ではxlsxのファイルを作ってしまいます。 Type exFormat = Type.GetTypeFromProgID("Excel.XlFileFormat.xlExcel8"); のような感じで使えるかとも思ったのですが、できませんでした。。 わかる方がいましたら、よろしくお願いします。 開発環境   Vista   VisualStudio2008   .NET Framework 3.5

  • C#で実行時にメソッドの返り値の型を変化させる

    C# で、実行時にメソッドの返り値の型を変化させることは可能でしょうか? たとえば、 public class MyData { object o; public void setValue( object a ) { o = a; } public object getValue() { return o; } } というクラスがあるとき、 static void Main(string[] args) { MyData a = new MyData(); a.setValue( 3 ); Console.WriteLine( a.getValue().GetType().ToString() ); int i = (int)a.getValue(); } というコードを実行すると、 System.Int32 と表示されます。Main の 4 行目で、(int)のキャストをはずすと、object から int への暗黙の変換はできませんというコンパイルエラーになります。 この(int)のキャストをしなくてもエラーにならないような getValue の関数はできないでしょうか? o は、数値型であるとします。 たとえば、MyData に、 public int getInt() { return (int)o; } とすれば、必ず int を返すようなメソッドはできると思うのですが、これだと、getByte() や、getDouble() などのように、考えられるすべての型を想定してメソッドを作ることになってしまいます。 そうではなく、getValue() で、少なくとも数値型の暗黙の変換はしてくれるようなことにできないでしょうか。 よろしくお願いします。

  • Openメソッドについて

    ブックAのSheet1にあるセルのデータをブックBのSheet1のセルにコピーするために、以下のようにOpenメソッドを使ったVBAを記述してみたのですが、エラーコード1004「指定されたファイルが存在しません」のようなエラーメッセージが出てきました。Openメソッドが使われている例を見ているとどうやらブックのあるフォルダを指定しているような感じがするのですが、Openメソッドは具体的に該当のブックのある場所を指定しなくてはならないのでしょうか??(私がVBAを記述するにあたり参考にしたインターネットのVBAを紹介するページでは、ブックのある場所を指定せず、私が記述したように直にブック名を入力していました。) お忙しい中申し訳ないのですが、どなたかご教授いただけると、とても嬉しいです!よろしくお願いいたします。 Sub ブックAのデータをブックBに() With Workbooks.Open("ブックA.xlsx")  .Sheets("Sheet1").Range("E8").Value = _ ThisWorkbook.Range("C2").Value End With End Sub

  • クラス、メソッド、プロパティ、変数などの意味は?

    いろんなサイトやネットでいろいろ調べたのですが、 よく分かりませんでした。自分なりに考えたことですが、 (1)~(6)の用語の内容とコード上での色付けは正しいでしょうか? (1)クラス(緑枠) コンストラクタ、メソッド、プロパティを一括りにまとめたパッケージのこと。 つまり、functionの【{】と【}】の間にあるもの。 (2)オブジェクト(青枠) 関数。すなわち「複数の物や動作を入れる物」。 つまりfunctionで始まるものをオブジェクトと呼ぶ。 (3)コンストラクタ(= クラス名または関数名)(紫枠) 「構築子」のこと。オブジェクトを作る名前の部分。 つまりfunction直後に付ける関数名(クラス名)をコンストラクタと呼ぶ。 (4)プロパティ(赤枠) 「特徴」のこと。 つまりfunction内で指定された変数(var b)をプロパティと呼ぶ。 function a(){var b;}; (5)メソッド(水色枠) 「動作」のこと。 つまりオブジェクト(functionで始まるもの)が 変数(var b)に指定された場合はメソッドと呼ぶ。 var b = function a(){}; (6)変数(灰色枠) function外で指定された変数(var b)は、変数と呼ぶ。 function a(){}; var b;

  • C#のmshtmlで・・・

    C#にてmshtmlでHTMLDocumentを取得したいのです。 ブラウザコントロールを使って、以下のようにして取得することはできたのですが、 AxSHDocVw.AxWebBrowser myWebBrowser = new AxSHDocVw.AxWebBrowser(); // ドキュメントオブジェクトの獲得 mshtml.HTMLDocument myDocument = (mshtml.HTMLDocument)axWebBrowser1.Document;     mshtml単体で取得しようとしてもうまくいきません。 VB.netのサンプル紹介ページを参考にして createDocumentFromUrl(url, null); を使用してもエラーになってしまします。 どのサイトを指定しても例外が発生してしまいどうすればいいのか困っております 解決方法をご存知の方、ご教授お願いします

  • Stringクラスのlengthメソッドについて

    こんにちは、Stringクラスのlengthメソッドについて質問させてください。 今まで配列のlengthは、宣言時に長さが決定するからメソッドではなく、finalフィールドで十分。 ArrayListだとかは長さが変わるからメソッドという意識を持っていました。 (カプセル化の概念とも関わりますが) 先日その話しをしていたら、「でも文字列(Stringオブジェクト)の長さも不変だよね。」と言われました。 確かに文字列の長さは不変なのに、長さの取得にはメソッドを使っています。 言語仕様として一貫性を持たせるなら、配列もlengthメソッドにするか、文字列をlengthフィールドにしたほうが綺麗だと思うんです。 Stringクラスのソースコードを見ていたら、文字列の長さは内部的に private int count; と宣言されていました。 そして、lengthメソッドは return count; しているだけでした。 ただ、このcountフィールドに値を代入しているのはコンストラクタ内だけだったので、 public final int length; とすれば、良かったのでは?と思いました。 この考えについて、 それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。 よろしくお願致します。

  • Array.sortメソッドのデフォルト比較関数

    JavaScriptのArray.sortメソッドは、 引数を指定しなければデフォルトの比較関数でソートされますが、 この比較関数を取り出して利用できないでしょうか。 要件は、プロパティ[name]と[value]を持ったオブジェクトの配列のソートです。 nameプロパティは半角英数字の文字列で、これをキーにソートしたいと考えています。 ソートの基準は、Array.sortのデフォルトと同じです。 つまり、こんなコードを想定しています。 var ary = [o1, o2, o3]; // o1~o3はそれぞれ上記のオブジェクト ary.sort(function(a, b){ return compare(a.name, b.name); }); このコードにおけるcompare関数を、Array.sortのデフォルト比較関数にしたいのですが、 これは自前で作成するしかないのでしょうか。 数値だけでなく文字列全般の比較になるので、結構実装が面倒そうなのですが、 自作する場合に何か使えそうな標準関数等、無いでしょうか。 今のところ思いついているのは、下記みたいなものです。 var compare = function(a, b) {  var temp = [a, b];  temp = temp.sort();  return temp[0] === a ? -1 : 1; } 比較関数内で更にArray.sortを呼んで2項目をソートし、 順番が入れ替わったかどうかを判定するだけです。 何だか冗長で気持ち悪いコードですので、代案を探しています。

  • JDBCドライバーのロードに関して

    参考書やwebページのソースコードにJDBCドライバーのロードのときに、Class.forName("...")と書いているものと、Class.forName("...").newInstance()と書いているものがあります。[...部分は省略]この二つのコードは、どこが違うのでしょうか。また、Sunmicroのホームページで、forNameメソッドは、"指定された文字列名を持つクラスまたはインタフェースに関連付けられた、Class オブジェクトを返します。"と、newInstanceメソッドは、"この Class オブジェクトが表すクラスの新しいインスタンスを生成します。"と書かれていますが、どうしてこれで、JDBCドライバーがロードされるのですか?また、初歩的な質問ですが、JDBCドライバーがロードされるというのは、どうゆうことですか?教えてください。

    • ベストアンサー
    • Java
  • C#の動的キャスト

    いつもお世話になっています。 C#の動的キャストに関する質問です。 C#のメソッドにobjectの引数を渡して動的にキャストする場合 void Hoge(object obj) { Type t = Type.GetType(obj); objの型 obj2 = (objの型)Convert.ChangeType(obj, t); //(1) ................................. } のようにされています。 しかし多様性をもつobjcetを引数にする多くの場合は「objの型」は不定です。 逆に言えば「objの型」がわかっている場合はわざわざobjectを引数にする必要はないわけです。 そこで質問ですが、何とかType t から「objの型」を取得して(1)記法による動的キャストを行う方法はないでしょうか? GetMethod, GetPropertyでメソッド,プロパティを取得し、Invoke, GetValue, SetValueすることは可能ですが、できればドット記法(.)が使える (1) のような動的キャストを行いたいと考えています。 よろしくお願いします。

専門家に質問してみよう