Typeを通ります.InvokeMethod実装方法のリロード

15628 ワード

バージョン:.NET Framework 3.5

まず、反射呼び出し方法の例を示します。


 
using System;

using System.Reflection;



class Example

{

    static void Main()

    {

        Type t = typeof(String);



        MethodInfo substr = t.GetMethod("Substring", 

            new Type[] { typeof(int), typeof(int) });

		//  MethodBase Invoke(object obj, object[] parameters) 

        Object result = 

            substr.Invoke("Hello, World!", new Object[] { 7, 5 });//  String Substring(int startIndex, int length) 

        Console.WriteLine("{0} returned \"{1}\".", substr, result);

    }

}



/*  :

System.String Substring(Int32, Int32) returned "World".

 */

 

本題に入る:Type.InvokeMethod実装方法のリロード


 
 

1)typeの紹介


TypeはSystem.Reflection機能のルートは、メタデータにアクセスする主な方法でもあります.Typeのメンバーを使用して、コンストラクション関数、メソッド、フィールド、プロパティ、クラスのイベントなど、タイプ宣言に関する情報を取得し、クラスを配置するモジュールおよびプログラムセットを取得します.マルチスレッドスキームでは、タイプオブジェクトをロックしてstaticデータへのアクセスを同期しないでください.他の制御されていないコードもクラスタイプをロックする可能性があります.これはデッドロックを引き起こす可能性があります.プライベートstaticオブジェクトをロックすることで、静的データへのアクセスを同期する必要があります.このクラスはスレッドが安全です.複数のスレッドは、このタイプのインスタンスから同時にデータを読み出すことができます.Typeの例は、クラス値タイプ配列インタフェースポインタが汎用タイプと汎用タイプ定義を構築する汎用タイプ、汎用タイプ定義、および汎用メソッド定義のタイプ実パラメータおよびタイプパラメータを列挙する任意のタイプを表すことができる.
 

2)例


 
Assembly assembly = Assembly.LoadFrom(sDllName);

Type fType = assembly.GetType(sClassName);

object instance = Activator.CreateInstance (fType);

fType.InvokeMember("classmethod",BindingFlags.InvokeMethod,null,instance,sParams);// instance classmethod ,sParams , , 

 

3)拡張


列挙クラスBindingFlagsの各属性の意味
Defaultはバインドフラグを指定しません.IgnoreCaseは、バインド時にメンバー名の大文字と小文字を考慮しないことを指定します.DeclaredOnlyは、提供されたタイプの階層レベルで宣言されたメンバーのみを考慮するように指定します.メンバーの継承は考慮されません.Instanceは、インスタンスメンバーが検索に含まれることを指定します.Staticは、静的メンバーが検索に含まれることを指定します.Publicは、検索に公開メンバーが含まれることを指定します.NonPublicは、非公開メンバーが検索に含まれることを指定します.FlattenHierarchyは、階層上の共通の静的メンバーと保護された静的メンバーを返すように指定します.継承クラスのプライベート静的メンバーは返されません.静的メンバーには、フィールド、メソッド、イベント、およびプロパティが含まれます.ネストされたタイプは返されません.InvokeMethodはメソッドを呼び出すことを指定します.コンストラクション関数またはタイプ初期値設定項目ではありません.CreateInstanceは、[反射](Reflection)を指定して、指定したタイプのインスタンスを作成する必要があります.与えられたパラメータに一致するコンストラクション関数を呼び出します.指定したメンバー名は無視されます.検索タイプが指定されていない場合は、(Instance|Public)が適用されます.呼び出しタイプ初期値設定項目は不可能です.GetFieldは、指定したフィールドに戻る値を指定します.SetFieldは、指定したフィールドを設定する値を指定します.GetPropertyは、指定した属性を返す値を指定します.SetPropertyは、指定した属性を設定する値を指定します.COM属性の場合、このバインディングフラグを指定することは、PutDispPropertyとPutRefDispPropertyを指定することと同等です.PutDispPropertyは、COMオブジェクトを呼び出すPRPPUTメンバーを指定します.PROPUTは、使用値の属性設定関数を指定します.プロパティにPRPPUTとPRPPUTREFが同時に存在し、どちらを呼び出すかを区別する必要がある場合は、PutDispPropertyを使用します.PutRefDispPropertyは、COMオブジェクトを呼び出すPRPPUTREFメンバーを指定します.PROPUTREFは、値ではなく参照を使用する属性設定関数を指定します.プロパティにPRPPUTとPRPPUTREFが同時に存在し、どちらを呼び出すかを区別する必要がある場合は、PutRefDispPropertyを使用します.ExactBinding指定パラメータのタイプは、対応するパラメータのタイプと完全に一致する必要があります.呼び出し元が空でないBinderオブジェクトを提供する場合、「反射」は、呼び出し元が提供するBindToXXXインプリメンテーションで適切な方法を選択することを意味するため、例外を引き起こす.SuppressChangeTypeは実装されていません.OptionalParamBindingは、パラメータの数と一致するメンバーセットを返します.このバインドフラグは、バンドパラメータにデフォルト値を持つメソッドと変数パラメータ(varargs)を持つメソッドに使用されます.このフラグはTypeのみとする.InvokeMemberと一緒に使用します.IgnoreReturnはCOM interopでメンバーを無視できる戻り値を指定します.例を挙げる
 
 
using System;

using System.Reflection;

using System.IO;



namespace BindingFlagsSnippet

{

    class EntryPoint

    {

        static void Main(string[] args)

        {

            Invoke.Go();

        }

    }





    class Invoke

    {

        public static void Go()

        {

            // BindingFlags.InvokeMethod

            // Call a static method.

            Type t = typeof (TestClass);



            Console.WriteLine();

            Console.WriteLine("Invoking a static method.");

            Console.WriteLine("-------------------------");

            t.InvokeMember ("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object [] {});



            // BindingFlags.InvokeMethod

            // Call an instance method.

            TestClass c = new TestClass ();

            Console.WriteLine();

            Console.WriteLine("Invoking an instance method.");

            Console.WriteLine("----------------------------");

            c.GetType().InvokeMember ("AddUp", BindingFlags.InvokeMethod, null, c, new object [] {});

            c.GetType().InvokeMember ("AddUp", BindingFlags.InvokeMethod, null, c, new object [] {});



            // BindingFlags.InvokeMethod

            // Call a method with parameters.

            object [] args = new object [] {100.09, 184.45};

            object result;

            Console.WriteLine();

            Console.WriteLine("Invoking a method with parameters.");

            Console.WriteLine("---------------------------------");

            result = t.InvokeMember ("ComputeSum", BindingFlags.InvokeMethod, null, null, args);

            Console.WriteLine ("{0} + {1} = {2}", args[0], args[1], result);



            // BindingFlags.GetField, SetField

            Console.WriteLine();

            Console.WriteLine("Invoking a field (getting and setting.)");

            Console.WriteLine("--------------------------------------");

            // Get a field value.

            result = t.InvokeMember ("Name", BindingFlags.GetField, null, c, new object [] {});

            Console.WriteLine ("Name == {0}", result);

            // Set a field.

            t.InvokeMember ("Name", BindingFlags.SetField, null, c, new object [] {"NewName"});

            result = t.InvokeMember ("Name", BindingFlags.GetField, null, c, new object [] {});

            Console.WriteLine ("Name == {0}", result);



            Console.WriteLine();

            Console.WriteLine("Invoking an indexed property (getting and setting.)");

            Console.WriteLine("--------------------------------------------------");

            // BindingFlags.GetProperty

            // Get an indexed property value.

            int  index = 3;

            result = t.InvokeMember ("Item", BindingFlags.GetProperty, null, c, new object [] {index});

            Console.WriteLine ("Item[{0}] == {1}", index, result);

            // BindingFlags.SetProperty

            // Set an indexed property value.

            index = 3;

            t.InvokeMember ("Item", BindingFlags.SetProperty, null, c, new object [] {index, "NewValue"});

            result = t.InvokeMember ("Item", BindingFlags.GetProperty , null, c, new object [] {index});

            Console.WriteLine ("Item[{0}] == {1}", index, result);



            Console.WriteLine();

            Console.WriteLine("Getting a field or property.");

            Console.WriteLine("----------------------------");

            // BindingFlags.GetField

            // Get a field or property.

            result = t.InvokeMember ("Name", BindingFlags.GetField | BindingFlags.GetProperty, null, c, new object [] {});

            Console.WriteLine ("Name == {0}", result);

            // BindingFlags.GetProperty

            result = t.InvokeMember ("Value", BindingFlags.GetField | BindingFlags.GetProperty, null, c, new object [] {});

            Console.WriteLine ("Value == {0}", result);



            Console.WriteLine();

            Console.WriteLine("Invoking a method with named parameters.");

            Console.WriteLine("---------------------------------------");

            // BindingFlags.InvokeMethod

            // Call a method using named parameters.

            object[] argValues = new object [] {"Mouse", "Micky"};

            String [] argNames = new String [] {"lastName", "firstName"};

            t.InvokeMember ("PrintName", BindingFlags.InvokeMethod, null, null, argValues, null, null, argNames);



            Console.WriteLine();

            Console.WriteLine("Invoking a default member of a type.");

            Console.WriteLine("------------------------------------");

            // BindingFlags.Default

            // Call the default member of a type.

            Type t3 = typeof (TestClass2);

            t3.InvokeMember ("", BindingFlags.InvokeMethod | BindingFlags.Default, null, new TestClass2(), new object [] {});



            // BindingFlags.Static, NonPublic, and Public

            // Invoking a member by reference.

            Console.WriteLine();

            Console.WriteLine("Invoking a method by reference.");

            Console.WriteLine("-------------------------------");

            MethodInfo m = t.GetMethod("Swap");

            args = new object[2];

            args[0] = 1;

            args[1] = 2;

            m.Invoke(new TestClass(),args);

            Console.WriteLine ("{0}, {1}", args[0], args[1]);

            // The string is case-sensitive.

            Type type = Type.GetType("System.String");



            // Check to see if the value is valid. If the object is null, the type does not exist.

            if (type == null)

            {

                Console.WriteLine("Please ensure that you specify only valid types in the type field.");

                Console.WriteLine("The type name is case-sensitive.");

                return;

            }

            // Declare and populate the arrays to hold the information.

            // You must declare either NonPublic or Public with Static or the search will not work.

            FieldInfo [] fi = type.GetFields (BindingFlags.Static |

                BindingFlags.NonPublic | BindingFlags.Public);

            // BindingFlags.NonPublic

            MethodInfo [] miNonPublic = type.GetMethods (BindingFlags.Static |

                BindingFlags.NonPublic);

            // BindingFlags.Public

            MethodInfo [] miPublic = type.GetMethods (BindingFlags.Static |

                BindingFlags.Public);



            // Iterate through all the nonpublic methods.

            foreach (MethodInfo method in miNonPublic)

            {

                Console.WriteLine(method);

            }

            // Iterate through all the public methods.

            foreach (MethodInfo method in miPublic)

            {

                Console.WriteLine(method);

            }

            // Iterate through all the fields.

            foreach (FieldInfo f in fi)

            {

                Console.WriteLine(f);

            }



            // BindingFlags.Instance

            // Call an instance method.

            TestClass tc = new TestClass ();

            Console.WriteLine();

            Console.WriteLine("Invoking an Instance method.");

            Console.WriteLine("----------------------------");

            tc.GetType().InvokeMember ("AddUp", BindingFlags.Public |

                BindingFlags.Instance | BindingFlags.CreateInstance,

                null, tc, new object [] {});



            // BindingFlags.CreateInstance

            // Calling and creating an instance method.

            Console.WriteLine();

            Console.WriteLine("Invoking and creating an instance method.");

            Console.WriteLine("-----------------------------------------");

            tc.GetType().InvokeMember ("AddUp", BindingFlags.Public |

                BindingFlags.Instance | BindingFlags.CreateInstance,

                null, tc, new object [] {});



            // BindingFlags.DeclaredOnly

            TestClass tc2 = new TestClass();

            Console.WriteLine();

            Console.WriteLine("DeclaredOnly members");

            Console.WriteLine("---------------------------------");

            System.Reflection.MemberInfo[] memInfo =

                tc2.GetType().GetMembers(BindingFlags.DeclaredOnly);

            for(int i=0;i<memInfo.Length;i++)

            {

                Console.WriteLine(memInfo[i].Name);

            }



            // BindingFlags.SuppressChangeType

            TestClass obj = new TestClass();

            Console.WriteLine();

            Console.WriteLine("Invoking static method - PrintName");

            Console.WriteLine("---------------------------------");

            System.Reflection.MethodInfo methInfo =

                obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.SuppressChangeType |

                BindingFlags.InvokeMethod, null,new object[]

                {"Brad","Smith"},null);



            // BindingFlags.IgnoreCase

            Console.WriteLine();

            Console.WriteLine("Using IgnoreCase and invoking the PrintName method.");

            Console.WriteLine("---------------------------------------------------");

            methInfo = obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.IgnoreCase |

                BindingFlags.InvokeMethod, null,new object[]

                {"brad","smith"},null);



            // BindingFlags.IgnoreReturn

            Console.WriteLine();

            Console.WriteLine("Using IgnoreReturn and invoking the PrintName method.");

            Console.WriteLine("-----------------------------------------------------");

            methInfo = obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.IgnoreReturn |

                BindingFlags.InvokeMethod, null,new object[]

                {"Brad","Smith"},null);



            // BindingFlags.OptionalParamBinding

            Console.WriteLine();

            Console.WriteLine("Using OptionalParamBinding and invoking the PrintName method.");

            Console.WriteLine("-------------------------------------------------------------");

            methInfo = obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.OptionalParamBinding |

                BindingFlags.InvokeMethod, null,new object[]

                {"Brad","Smith"},null);



            // BindingFlags.ExactBinding

            Console.WriteLine();

            Console.WriteLine("Using ExactBinding and invoking the PrintName method.");

            Console.WriteLine("-----------------------------------------------------");

            methInfo = obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.ExactBinding |

                BindingFlags.InvokeMethod, null,new object[]

                {"Brad","Smith"},null);



            // BindingFlags.FlattenHierarchy

            Console.WriteLine();

            Console.WriteLine("Using FlattenHierarchy and invoking the PrintName method.");

            Console.WriteLine("---------------------------------------------------------");

            methInfo = obj.GetType().GetMethod("PrintName");

            methInfo.Invoke(obj,BindingFlags.FlattenHierarchy |

                BindingFlags.InvokeMethod, null,new object[]

                {"Brad","Smith"},null);

        }

    }