2: Quelle est l'application et la méthode d'appel de réflexion et de réflexion

Préface

Processus de compilation du programme

1. ILspy: rétro-ingénierie: vous pouvez décompiler le fichier Dll / Exe
2. IL: est le code marqué en code C #, pas
facile à lire 3. métadonnées: c'est une liste de données, enregistrez simplement ce qui est là, pas Afficher toutes les implémentations, grand livre détaillé
4. Reflection est l'espace de noms System.Reflection, qui peut lire les métadonnées et utiliser les métadonnées; c'est une bibliothèque d'aide fournie par Microsoft;
5. La figure suivante montre un exemple d'utilisation d'ILSpy pour ouvrir une classe d'entité que j'ai écrite. Si vous utilisez la méthode IL, le programme que nous voyons n'est pas très clair.
LES
6. Si vous utilisez C # pour afficher, vous pouvez obtenir le code que j'ai écrit à l'origine.
c #

Pourquoi apprendre le réflexe

Réponse: Parce que la réflexion est vraiment partout, ORM / MVC / IOC;

  1. Dans la programmation MVC, un chemin tel que "Home / Index" est utilisé pour accéder à une classe spécifique dans le fichier programme. La chose pratique est la réflexion.
  2. Vous pouvez utiliser la réflexion pour générer des objets d'entité.
  3. Vous pouvez utiliser la réflexion pour générer des instructions de requête automatiques et renvoyer des objets basés sur des classes d'entités.
  4. La réflexion peut réaliser le découplage du programme (la classe peut être utilisée sans ajouter de références de projet).
  5. La réflexion peut réaliser une configuration dynamique pour atteindre une haute disponibilité du programme.

1. Réflexion pour créer des objets

Structure du répertoire

1. La structure actuelle est celle illustrée ci-dessus. La méthode d'appel est comme indiqué dans la figure et le code.
Obtenir le graphique d'objet
2. Il existe de nombreuses façons de charger la bibliothèque dynamique dll, il est recommandé d'utiliser cette méthode Assembly.LoadFrom Reason:

  • Pas besoin d'ajouter une référence à la dll, copiez simplement la dll dans le répertoire de version à utiliser.
  • Pas besoin du chemin complet, écrivez simplement le nom de DLl. PS: Le suffixe doit être ajouté avec .dll
public static IDBHelper getClass()
        {
    
    
            //获取数据清单metadata
            Assembly assembly3 = Assembly.LoadFrom(@"HomeWork.SqlHelper.dll"); //dll名称(需要后缀) 
            ///2.获取类型
            Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");
            //创建实例
            object obj = Activator.CreateInstance(type);
            //类型转换。
            return obj as IDBHelper;
        }

2. Méthode d'appel de réflexion

通过在上边的简单工厂后,我们实例出来一个接口对象IDBHelper。
接下来就可以通过接口点方法进行使用。

Méthode d'appel

			Console.WriteLine("获取反射类开始!");
            IDBHelper iDBHelper = SimpleFactory.getClass();
            5.调用方法
            Company company = iDBHelper.Find(1);
            Console.WriteLine("获取反射类完成!");

3. Réfléchissez pour appeler la méthode de construction avec des paramètres

{
    
     
                Console.WriteLine("*********************Reflection创建带构造函数参数的对象*************************");
                Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  
                Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");
                object obj = Activator.CreateInstance(type);
                object obj1 = Activator.CreateInstance(type, new object[] {
    
     "你好" });
                object obj2 = Activator.CreateInstance(type, new object[] {
    
     123 });
                object obj3 = Activator.CreateInstance(type, new object[] {
    
     123, "你好" });
                Type type1 = typeof(SqlServerHelper);
            }

Méthode de paramètre d'appel

4. Méthode d'appel de réflexion

{
    
    
    //Type type1 = typeof(ReflectionTest);
    //普通调用方式
    ReflectionTest reflectionTest = new ReflectionTest();
    reflectionTest.Show1();
    reflectionTest.Show2(123);
    reflectionTest.Show3(123);
    //reflectionTest.Show4
    ReflectionTest.Show5("Richard");

    //Console.WriteLine("*********************Reflection调用普通方法*************************");
    Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  
    Type type = assembly3.GetType("HomeWork.SqlHelper.ReflectionTest");
    object objTet = Activator.CreateInstance(type);
    //objTet.Show();
    MethodInfo Show1 = type.GetMethod("Show1");
    object oResutl1 = Show1.Invoke(objTet, new object[] {
    
     });
    object oResutl = Show1.Invoke(objTet, new object[0]);

    MethodInfo Show2 = type.GetMethod("Show2");
    object oResutl2 = Show2.Invoke(objTet, new object[] {
    
     123 });

    //Console.WriteLine("*********************Reflection调用普重载方法*************************");
    MethodInfo Show33 = type.GetMethod("Show3",new Type[] {
    
     typeof(DateTime)});
    object oResutl33 = Show33.Invoke(objTet, new object[] {
    
     DateTime.Now });
    Console.WriteLine($"{ typeof(DateTime) }>>>>>oResutl33执行完的参数值{oResutl33}");


    MethodInfo Show3 = type.GetMethod("Show3", new Type[] {
    
     typeof(int), typeof(string) });
    object oResutl3 = Show3.Invoke(objTet, new object[] {
    
     123, "阳光下的微笑" });

    MethodInfo Show3_1 = type.GetMethod("Show3", new Type[] {
    
     typeof(string), typeof(int) });
    object oResutl3_1 = Show3_1.Invoke(objTet, new object[] {
    
     "明日梦", 234 });

    MethodInfo Show3_2 = type.GetMethod("Show3", new Type[] {
    
     typeof(int) });
    object oResutl3_2 = Show3_2.Invoke(objTet, new object[] {
    
     345 });

    MethodInfo Show3_3 = type.GetMethod("Show3", new Type[] {
    
     typeof(string) });
    object oResutl3_3 = Show3_3.Invoke(objTet, new object[] {
    
     "赤" });

    MethodInfo Show3_4 = type.GetMethod("Show3", new Type[0]);
    object oResutl3_4 = Show3_4.Invoke(objTet, new object[] {
    
     });

    Console.WriteLine("*********************Reflection调用私有方法*************************");
    MethodInfo Show4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance);
    object oResutl4 = Show4.Invoke(objTet, new object[] {
    
     "伟文" });

    MethodInfo Show5 = type.GetMethod("Show5", BindingFlags.Static | BindingFlags.Public);
    object oResutl5 = Show5.Invoke(objTet, new object[] {
    
     "追逐梦想的人。。" });
    object oResutl5_1 = Show5.Invoke(null, new object[] {
    
     "you。。" });

}

5. Classe générique d'appel réfléchissant + méthode générique

Console.WriteLine("*********************Reflections实例化泛型类+调用泛型方法*************************");
{
    
    
    GenericMethod genericMethod = new GenericMethod();
    genericMethod.Show<int, string, DateTime>(123, "黄大仙", DateTime.Now);
    Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  
    Type type = assembly3.GetType("HomeWork.SqlHelper.GenericMethod");
    object genericTest = Activator.CreateInstance(type);
    MethodInfo show = type.GetMethod("Show");
    //注意:需要指定泛型方法的泛型类型
    MethodInfo show1 = show.MakeGenericMethod(new Type[] {
    
     typeof(int), typeof(string), typeof(DateTime) });
    show1.Invoke(genericTest, new object[] {
    
     123, "黄大仙", DateTime.Now });//如果是泛型方法,需要先确定类型,再执行方法,注意:指定的类型和传入的参数类型必须匹配
}
//泛型类
{
    
    
    Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  
    Console.WriteLine(typeof(GenericClass<,,>));
    //下面的方法未能成功获取到原因由于它是泛型类。要在声明类的时候就告知参数类型
    //Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");                    
    //MethodInfo show = type.GetMethod("Show");
    //MethodInfo show2 = show.MakeGenericMethod(new Type[] { typeof(DateTime), typeof(int), typeof(string) });

    Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");
    Type type1 = type.MakeGenericType(new Type[] {
    
     typeof(int), typeof(string), typeof(DateTime) });
    object genericObj = Activator.CreateInstance(type1);
    MethodInfo show1 = type1.GetMethod("Show");
    show1.Invoke(genericObj, new object[] {
    
     234, "工程师 冯", DateTime.Now });

    //GenericClass genericClass = new DB.SqlServer.GenericClass();
    GenericClass<int, string, DateTime> genericClass = new GenericClass<int, string, DateTime>();
    genericClass.Show(234, "工程师 冯", DateTime.Now);
}

6. Problèmes de performance de réflexion

  • Vous pouvez utiliser Stopwatch pour surveiller le temps nécessaire pour obtenir la bibliothèque dynamique, puis pour le processus d'instance. Il peut être testé en boucle.
  • Après les tests, on constate en effet que la réflexion entraînera des problèmes de performances. Cependant, obtenir des bibliothèques dynamiques et créer des objets prend du temps.
  • Mais c'est le cas de nombreux cycles. Cela peut être évité grâce à l'optimisation du code. tel que. Vous n'obtiendrez pas du tout autant d'objets dans la boucle. Mettez simplement l'objet d'acquisition en dehors de la boucle.
  • De cette façon, la différence de vitesse peut être ignorée.
    Certains des avantages dont l'enseignant a parlé
    // Découplage: supprimez la dépendance aux détails
    // Si votre entreprise a un nouveau responsable technique; disons que vous voulez vous engager dans MySql
    // réflexion pour le faire,
    // 1. Il suffit d'implémenter MySqlHelper,
    / / 2.Copier le fichier Dll
    // 3. Modifier le fichier de configuration
    // Changer la version de la base de données
    // Réaliser la configurabilité du programme; extension du programme;
    // La réflexion détruit un singleton
    // La réflexion peut percer l'autorité de la méthode limite;

7. Application de la réflexion dans le cadre

反射:IOC
反射应用于哪些框架;
IOC框架;反射+配置文件+工厂==IOC框架中应用;
反射--MVC
dll: HomeWork.SqlHelper.dll
type: HomeWork.SqlHelper.GenericDouble
就可以创建对象
type可以获取到Method===Method名称--字符串
  dll名称+类名称+方法名称===可以调用这个方法 
 localhost://Home/Index/123== 可以调用到MVC项目中的某一个Action,你们觉得这是用的什么技术?
MVC中调用方法就是反射的真实写照。。

反射在ORM中的应用: 
ORM---对象关系映射,就是通过对类的达成对数据库的操作;
方法、属性、字段

8. Encapsuler l'accès à la base de données ORM

//控制台程序
{
    
    
    SqlServerHelper sqlServerHelper = new SqlServerHelper();
    //Company company = sqlServerHelper.QueryCompany(1); 
    Company company = sqlServerHelper.Find<Company>(1);
    User user = sqlServerHelper.Find<User>(1);
    Console.WriteLine(company);
    Console.WriteLine(user);
}


//SqlServerHelper中的方法,通过反射结合泛型就能实现数据的查询。经过小扩展可以实现删除与添加数据。
public T Find<T>(int id) where T : BaseModel
        {
    
    
            string constr = "server=.;database=CustomerDB;uid=sa;pwd=sasa";

            Type type = typeof(T);
            object oResult = Activator.CreateInstance(type);

            var propList = type.GetProperties().Select(p => $"[{p.Name}]");
            string props = string.Join(",", propList);

            string sql = $"select {props} from  [{type.Name}] where id={id}";
            using (SqlConnection con = new SqlConnection(constr)) {
    
    
                using (SqlCommand command=new SqlCommand())
                {
    
    
                    command.Connection = con;
                    command.CommandText = sql;
                    con.Open();
                    SqlDataReader reader = command.ExecuteReader();
                    if (reader.Read())
                    {
    
    
                        foreach (PropertyInfo prop in type.GetProperties())
                        {
    
    
                            prop.SetValue(oResult, reader[prop.Name]);
                        }
                    }
                }
            }
            return oResult as T;
        }

Je suppose que tu aimes

Origine blog.csdn.net/hello_mr_anan/article/details/107580088
conseillé
Classement