10分で反射の理解を教えます

50763 ワード

反射とは?


反射反射、プログラマーの楽しみ!はい.Net分野のプログラム設計では、反射はどこにでもある、MVC、ASP.Net、各種ORM、IOC、AOPのほとんどのフレームワークは反射から離れられない.逆コンパイルツールで使用される下位技術は反射ではなく、逆方向エンジニアリングです.
反射(Reflection,System.Reflection)は.Net Frameworkが提供するヘルプクラスライブラリで、Metadataで説明したデータ情報を読み取り、使用できます.メタデータ(Metadata)は、dll/exe内の各種情報を記述し、仲介データ、中継データとも呼ばれ、データを記述するデータ(data about data)であり、主にデータ属性(property)を記述する情報であり、記憶位置、履歴データ、リソース検索、ファイル記録などの機能をサポートする.

反射のメリットとデメリット:


利点:ダイナミック-既存のプログラムを破壊することなく、プログラムを良好に拡張できます.Eg:プロジェクトは最初はMysqlデータベースを使用していましたが、プロジェクトの状況が変化したためSqlServerデータベースに変更する必要があります.このようなプロジェクトのニーズに直面して、従来の解決策は、プロジェクトに新しいSqlServerデータベースアクセスコードを追加し、データベースアクセス実装層をSqlServerに変更し、最後にソースコードをコンパイルして再配布することである.
従来の解決方法の例の擬似コードは以下の通りである.
1                     IDBHelper iDBHelper = new MySqlHelper();
2                     IDBHelper iDBHelper = new SqlServerHelper();
3                     iDBHelper.Query();
反射のサンプルコードを使用するには、次の手順に従います.
 1 namespace ReflectionDemo
 2 {
 3     /// 
 4     ///     
 5     /// 
 6     public class SimpleFactory
 7     {
 8         //      
 9         private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelperConfig"];
10         //       dll  
11         private static string DllName = IDBHelperConfig.Split(',')[0]; 
12         //         
13         private static string TypeName = IDBHelperConfig.Split(',')[1];
14         /// 
15         ///                    
16         /// 
17         /// 
18         public static IDBHelper CreateInstance()
19         {
20             Assembly assembly = Assembly.Load(DllName);
21             Type type = assembly.GetType(TypeName);
22             object oDBHelper = Activator.CreateInstance(type);
23             IDBHelper iDBHelper = oDBHelper as IDBHelper;
24             return iDBHelper;
25         }
26     }
27 }
  "IDBHelperConfig" value="MySqlDb,MySqlDb.MySqlHelper"/>
                IDBHelper iDBHelper = SimpleFactory.CreateInstance();
                iDBHelper.Query();
反射によってプログラムの構成が実現され、プロファイルを変更することで実装クラスを自動的に切り替えることができ、実装クラスは事前に存在しなければならず、実装クラスを固定するのではなく、プロファイルによって実行され、反射によって作成される.拡張性:既存のコードをまったく変更せず、新しい実装、プロファイルの変更だけで、新しい機能をサポートできます.これが反射の動的特性です.
欠点:使用が面倒で、コンパイラの検査を避けてプログラム行を運ぶ時に異常が多くなり、性能の問題が発生します.

反射によるコンストラクタの呼び出し

  1 namespace SqlServerDb
  2 {
  3 
  4     /// 
  5     ///      
  6     /// 
  7     public class ReflectionTest
  8     {
  9         #region Identity
 10         /// 
 11         ///       
 12         /// 
 13         public ReflectionTest()
 14         {
 15             Console.WriteLine("   {0}       ", this.GetType());
 16         }
 17 
 18         /// 
 19         ///        
 20         /// 
 21         /// 
 22         public ReflectionTest(string name)
 23         {
 24             Console.WriteLine("   {0}    【string】    ", this.GetType());
 25         }
 26 
 27         public ReflectionTest(int id)
 28         {
 29             Console.WriteLine("   {0}    【int】    ", this.GetType());
 30         }
 31         #endregion
 32 
 33         #region Method
 34         /// 
 35         ///     
 36         /// 
 37         public void Show1()
 38         {
 39             Console.WriteLine("   {0} Show1", this.GetType());
 40         }
 41         /// 
 42         ///      
 43         /// 
 44         /// 
 45         public void Show2(int id)
 46         {
 47 
 48             Console.WriteLine("   {0} Show2", this.GetType());
 49         }
 50         /// 
 51         ///       
 52         /// 
 53         /// 
 54         /// 
 55         public void Show3(int id, string name)
 56         {
 57             Console.WriteLine("   {0} Show3", this.GetType());
 58         }
 59         /// 
 60         ///       
 61         /// 
 62         /// 
 63         /// 
 64         public void Show3(string name, int id)
 65         {
 66             Console.WriteLine("   {0} Show3_2", this.GetType());
 67         }
 68         /// 
 69         ///       
 70         /// 
 71         /// 
 72         public void Show3(int id)
 73         {
 74             Console.WriteLine("   {0} Show3_3", this.GetType());
 75         }
 76         /// 
 77         ///       
 78         /// 
 79         /// 
 80         public void Show3(string name)
 81         {
 82             Console.WriteLine("   {0} Show3_4", this.GetType());
 83         }
 84 
 85         /// 
 86         ///       
 87         /// 
 88         public void Show3()
 89         {
 90             Console.WriteLine("   {0} Show3_1", this.GetType());
 91         }
 92 
 93         /// 
 94         ///     
 95         /// 
 96         /// 
 97         private void Show4(string name)
 98         {
 99             Console.WriteLine("   {0} Show4", this.GetType());
100         }
101 
102         /// 
103         ///     
104         /// 
105         /// 
106         public static void Show5(string name)
107         {
108             Console.WriteLine("   {0} Show5", typeof(ReflectionTest));
109         }
110         #endregion
111     }
112 }
 1                 Assembly assembly = Assembly.Load("SqlServerDb");
 2                 Type type = assembly.GetType("SqlServerDb.ReflectionTest");
 3                 foreach (ConstructorInfo ctor in type.GetConstructors())
 4                 {
 5                     Console.WriteLine($"ctor.Name:{ctor.Name}");
 6                     foreach (var parameter in ctor.GetParameters())
 7                     {
 8                         Console.WriteLine($"ParameterType:{parameter.ParameterType},parameterName: {parameter.Name}");
 9                     }
10                 }
11                 object oTest1 = Activator.CreateInstance(type);
12                 object oTest2 = Activator.CreateInstance(type, new object[] { 123 });
13                 object oTest3 = Activator.CreateInstance(type, new object[] { "  " });

1                 //      ---            
2                 Assembly assembly = Assembly.Load("SqlServerDb");
3                 Type type = assembly.GetType("SqlServerDb.Singleton");
4                 Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
5                 Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
6                 Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonB)}");

び し クラス

namespace SqlServerDb
{

    /// 
    ///      
    /// 
    /// 
    /// 
    /// 
    public class GenericClass
    {
        public GenericClass()
        {
            Console.WriteLine("GenericClass         ");
        }


        public void Show(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }

    /// 
    ///       
    /// 
    public class GenericMethod
    {

        public GenericMethod()
        {
            Console.WriteLine("GenericMethod          。");
        }

        public void Show(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }

        
    }

    public class GenericDouble
    {
        public void Show(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }
}
1                 Assembly assembly = Assembly.Load("SqlServerDb");
2                 Type type = assembly.GetType("SqlServerDb.GenericClass`3");
3                 GenericClass<string, int, DateTime> genericClass = new GenericClass<string, int, DateTime>();
4                 //genericClass.Show("12", 1, DateTime.Now);
5                 //object oGeneric = Activator.CreateInstance(type);
6                 Type typeMake = type.MakeGenericType(new Type[] { typeof(string), typeof(int), typeof(DateTime) });
7                 object oGeneric = Activator.CreateInstance(typeMake);

び し メソッド

                Assembly assembly = Assembly.Load("SqlServerDb");
                Type type = assembly.GetType("SqlServerDb.GenericMethod");
                object oGeneric = Activator.CreateInstance(type);

してオブジェクトを した 、メソッド を っていたら、どのようにタイプ をしないで、 メソッドを び しますか?

 1    2                 Assembly assembly = Assembly.Load("SqlServerDb");
 3                 Type type = assembly.GetType("SqlServerDb.ReflectionTest");
 4                 object oTest = Activator.CreateInstance(type);
 5                 foreach (var method in type.GetMethods())
 6                 {
 7                     Console.WriteLine(method.Name);
 8                     foreach (var parameter in method.GetParameters())
 9                     {
10                         Console.WriteLine($"{parameter.Name}  {parameter.ParameterType}");
11                     }
12                 }
13                 {
14                     ReflectionTest reflection = new ReflectionTest();
15                     reflection.Show1();
16                 }
17                 {
18                     MethodInfo method = type.GetMethod("Show1");
19                     //if()
20                     method.Invoke(oTest, null);
21                 }
22                 {
23                     MethodInfo method = type.GetMethod("Show2");
24                     method.Invoke(oTest, new object[] { 123 });
25                 }
26                 {
27                     MethodInfo method = type.GetMethod("Show3", new Type[] { });
28                     method.Invoke(oTest, null);
29                 }
30                 {
31                     MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
32                     method.Invoke(oTest, new object[] { 123 });
33                 }
34                 {
35                     MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string) });
36                     method.Invoke(oTest, new object[] { "    " });
37                 }
38                 {
39                     MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
40                     method.Invoke(oTest, new object[] { 234, "    " });
41                 }
42                 {
43                     MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
44                     method.Invoke(oTest, new object[] { "PHS", 345 });
45                 }
46                 {
47                     MethodInfo method = type.GetMethod("Show5");
48                     method.Invoke(oTest, new object[] { "   " });//         
49                 }
50                 {
51                     MethodInfo method = type.GetMethod("Show5");
52                     method.Invoke(null, new object[] { "   " });//           
53                 }

び しプライベートメソッド

1             {
2                 //      
3                 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&    &&&&&&&&&&&&&&&&&&&");
4                 Assembly assembly = Assembly.Load("SqlServerDb");
5                 Type type = assembly.GetType("SqlServerDb.ReflectionTest");
6                 object oTest = Activator.CreateInstance(type);
7                 var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
8                 method.Invoke(oTest, new object[] { "    " });
9             }

び し メソッド

                Assembly assembly = Assembly.Load("SqlServerDb");
                Type type = assembly.GetType("SqlServerDb.GenericMethod");
                object oGeneric = Activator.CreateInstance(type);
                foreach (var item in type.GetMethods())
                {
                    Console.WriteLine(item.Name);
                }
                MethodInfo method = type.GetMethod("Show");
                //           
                var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
                object oReturn = methodNew.Invoke(oGeneric, new object[] { 123, "   ", DateTime.Now });

び し メソッドと クラス

1                 Assembly assembly = Assembly.Load("SqlServerDb");
2                 //          MakeGenericType         
3                 Type type = assembly.GetType("SqlServerDb.GenericDouble`1").MakeGenericType(typeof(int));
4                 object oObject = Activator.CreateInstance(type);
5                 MethodInfo method = type.GetMethod("Show").MakeGenericMethod(typeof(string), typeof(DateTime));
6                 method.Invoke(oObject, new object[] { 345, "    ", DateTime.Now });