C#基础知识学习——反射(十三)

定义

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。是一个帮助类库,可以读取dll/exe中元数据数据清单

        public class Book
        {
    
    

            public Book()
            {
    
    
                Console.WriteLine("空的构造函数");
            }

            private Book(string message)
            {
    
    
                Console.WriteLine($"带参数{
      
      message}的私有构造函数");
            }

        }
        public static void Test()
        {
    
    
            // 创建Book对象 【正常方式】
            var book = new Book();
            // 使用反射创建Book对象 【通过反射手段来创建实例】
            var bookType = typeof(Book);
            var bookInstance1 = Activator.CreateInstance(bookType);
            var bookInstance2 = Activator.CreateInstance(bookType, new object[] {
    
     "私有构造函数" }, true);
        }

C#创建dll

1.创建新建项目–添加–新建项目–类库
2.进行类的创建
3.在本项目:引用–添加引用–项目–将刚刚创建的项目引用进来
4.打开本项目文件夹–bin-debug文件夹下上找到dll文件

/// <summary>
/// 创建类库
/// </summary>
namespace DB
{
    
    
    public class DBHelper
    {
    
    

        public DBHelper()
        {
    
    
            Console.WriteLine($"无参数构造函数");
        }
        public DBHelper(string name, int ID)
        {
    
    
            Console.WriteLine($"name={
      
      name},ID={
      
      ID}");
        }
        public DBHelper(int ID, string name)
        {
    
    
            Console.WriteLine($"ID={
      
      ID},name={
      
      name}");
        }
        public DBHelper(string name, int ID, bool b)
        {
    
    
            Console.WriteLine($"name={
      
      name},ID={
      
      ID},bool={
      
      b}");
        }
        private DBHelper(int ID, string name, int ID1, string name1)
        {
    
    
            Console.WriteLine($"ID={
      
      ID},name={
      
      name},ID1={
      
      ID1},name1={
      
      name1}");
        }
        public string Query(int id)
        {
    
    
            return $"IDBHelper====>{
      
      id}";
        }
        public void Show1()
        {
    
    
            Console.WriteLine("我是无参数的函数");
        }
        public void Show2(string a)
        {
    
    
            Console.WriteLine($"我是有参数的函数,参数为{
      
      a}");
        }
        public void Show3(int a, string b)
        {
    
    
            Console.WriteLine($"我是有参数的函数,参数1为{
      
      a},参数2为{
      
      b}");
        }
        public void Show3(int a, int b)
        {
    
    
            Console.WriteLine($"我是有参数的函数--Show3重载函数之一,参数1为{
      
      a},参数2为{
      
      b}");
        }
        public void Show3()
        {
    
    
            Console.WriteLine($"我是无参数的函数--Show3重载函数之一");
        }
        private void Show4()
        {
    
    
            Console.WriteLine($"这里是{
      
      this.GetType()}的私有方法Show4");
        }
        private void Show4(string a)
        {
    
    
            Console.WriteLine($"这里是{
      
      this.GetType()}的私有方法Show4的重载,参数为{
      
      a}");
        }

        public static void Show5(string a)
        {
    
    
            Console.WriteLine($"这里是静态方法,参数为{
      
      a}");
        }
        public void Show6<T, Y, U>(T t, Y y, U u)
        {
    
    
            Console.WriteLine($"这里是泛型方法,参数为1{
      
      t},参数2为{
      
      y},参数3为{
      
      u}");
        }
    }
    public class FXclass<T, W, X>
    {
    
    
        public void Show(T t, W w, X x)
        {
    
    
            Console.WriteLine($"t.type={
      
      t.GetType().Name},w.type={
      
      w.GetType().Name},x.type ={
      
      x.GetType().Name}");
        } 
    }
    public class FXclass1<T>
    {
    
    
        public void Show<W,X>(T t, W w, X x)
        {
    
    
            Console.WriteLine($"t.type={
      
      t.GetType().Name},w.type={
      
      w.GetType().Name},x.type ={
      
      x.GetType().Name}");
        }
    }
    public class Person
    {
    
    
        public Person()
        {
    
    
            Console.WriteLine($"{
      
      this.GetType().FullName}被创建,");
        }            
        public int ID {
    
     get; set; }
        public string  Name {
    
     get; set; }

        public int Age {
    
     get; set; }

        public string Describe; 
    }
}

反射根据dll创建对象:三种创建对象方式、反射普通类、泛型类、反射赋值与取值

1.动态读取dll:
a:LoadFrom:dll全名称,需要后缀
b:LoadFile:全路径,需要dll后缀
c:Load:dll名称不需要后缀
2.获取类型:参数需要是类的全名称
Type type = assembly.GetType(“DB.IDBHelper”);
3.创建对象
var instance = (IDBHelper)Activator.CreateInstance(type!)!;
4.对象转换:
var instance = (IDBHelper)Activator.CreateInstance(type!)!;

var instance1 = Activator.CreateInstance(type!)!;
var instance = instance1 as IDBHelper;

public static void TestAssemly()
        {
    
      

            ///基于程序集方式获取Assembly对象
            Assembly assembly = Assembly.LoadFrom("DB.dll");
            Type type = assembly.GetType("DB.DBHelper");
            // var instance = (IDBHelper)Activator.CreateInstance(type!)!;
            var instance1 = Activator.CreateInstance(type!)!;
            var instance = instance1 as DBHelper;
            //c#8.0
            var result = instance.Query(100);
            Console.WriteLine(result);

            #region 普通类
            {
    
    
                ///基于程序集方式获取Assembly对象---构造函数
                Assembly assembly0 = Assembly.LoadFrom("DB.dll");
                Type type0 = assembly0.GetType("DB.DBHelper");
                var instance00 = Activator.CreateInstance(type0!, new object[] {
    
     55, "sdfb" })!;
                var instance10 = Activator.CreateInstance(type0!, new object[] {
    
     "hdfogfis", 88 })!;
                var instance20 = Activator.CreateInstance(type0!, new object[] {
    
     "trh", 159, false })!;
                //根据参数类型匹配对应构造函数
                ConstructorInfo constructorInfo = type0!.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] {
    
     typeof(int), typeof(string), typeof(int), typeof(string) }, null);
                constructorInfo.Invoke(new object[] {
    
     89, "dff", 79, "fdsg" });

                //获取所有构造函数
                ConstructorInfo[] constructorInfo1 = type0!.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

                foreach (var constructorIn in constructorInfo1)
                {
    
    
                    ParameterInfo[] parameterInfo = constructorIn.GetParameters();
                    foreach (var parame in parameterInfo)
                    {
    
    
                        Console.WriteLine($"{
      
      parame.ParameterType}==》{
      
      parame.Name}");
                    }
                }

                Console.WriteLine("调用无参的函数");
                object Instane = Activator.CreateInstance(type0!);

                MethodInfo methodInfo = type0.GetMethod("Show1")!;
                methodInfo.Invoke(Instane, new object[] {
    
     });
                methodInfo.Invoke(Instane, new object[0]);
                methodInfo.Invoke(Instane, null);
                Console.WriteLine("调用有参的函数");
                MethodInfo methodInfo0 = type0.GetMethod("Show2", new Type[] {
    
     typeof(string) })!;
                methodInfo0.Invoke(Instane, new object[] {
    
     "ndd" });

                Console.WriteLine("调用有参的重载函数");
                MethodInfo methodInfo1 = type0.GetMethod("Show3", new Type[] {
    
     typeof(int), typeof(string) })!;
                methodInfo1.Invoke(Instane, new object[] {
    
     998, "ndd" });
                MethodInfo methodInfo2 = type0.GetMethod("Show3", new Type[] {
    
     typeof(int), typeof(int) })!;
                methodInfo2.Invoke(Instane, new object[] {
    
     998, 0205 });
                MethodInfo methodInfo3 = type0.GetMethod("Show3", new Type[0])!;
                methodInfo3.Invoke(Instane, null);
                Console.WriteLine("调用私有函数");
                MethodInfo methodInfo4 = type0.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new Type[0], null)!;
                methodInfo4.Invoke(Instane, null);
                MethodInfo methodInfo5 = type0.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new Type[] {
    
     typeof(string) }, null)!;
                methodInfo5.Invoke(Instane, new object[] {
    
     "Show4" });

                Console.WriteLine("调用有参的静态方法----静态方法不需要实例");
                MethodInfo methodInfo6 = type0.GetMethod("Show5", new Type[] {
    
     typeof(string) })!;
                methodInfo6.Invoke(null, new object[] {
    
     "Show5" });

                Console.WriteLine("调用有参的泛型方法 ");
                MethodInfo methodInfo7 = type0.GetMethod("Show6")!;
                //获取到泛型方法后先确定类型
                MethodInfo methodInfo_generic = methodInfo7.MakeGenericMethod(new Type[] {
    
     typeof(string), typeof(int), typeof(DateTime) });
                methodInfo_generic.Invoke(Instane, new object[] {
    
     "fanxing ", 886, DateTime.Now });
            }
            #endregion

            #region 泛型类
            {
    
    
                Console.WriteLine("-----泛型方法泛型类型小于等于类泛型类型------");
                Assembly assembly0 = Assembly.LoadFrom("DB.dll");
                //泛型类的类型需要在类后面加占位符+泛型数
                Type type0 = assembly0.GetType("DB.FXclass`3");
                //确定泛型类类型
                Type generType = type0.MakeGenericType(new Type[] {
    
     typeof(string), typeof(int), typeof(DateTime) });
                object instance0 = Activator.CreateInstance(generType! )!;
                MethodInfo show = generType.GetMethod("Show");
                show.Invoke(instance0,new object[] {
    
     "fanxingfangfa",10,DateTime.Now});


                Console.WriteLine("-----泛型方法泛型类型多于类泛型类型------");
                //Assembly assembly1 = Assembly.LoadFrom("DB.dll");
                //泛型类的类型需要在类后面加占位符+泛型数
                Type type1 = assembly0.GetType("DB.FXclass1`1");
                //确定泛型类类型
                Type generType1 = type1.MakeGenericType(new Type[] {
    
     typeof(string) });
                object instance2 = Activator.CreateInstance(generType1!)!;
                MethodInfo show1 = generType1.GetMethod("Show");
                //确定方法类型
                MethodInfo methodInfo = show1.MakeGenericMethod(new Type[] {
    
     typeof(string), typeof(double) });
                methodInfo.Invoke(instance2, new object[] {
    
     "fanxingfangfa", "泛型", 88.888 });

            }
            #endregion

            #region 反射方式属性赋值取值、字段赋值取值
            {
    
    
                Console.WriteLine("-----反射方式属性赋值、取值------");
                Assembly assembly0 = Assembly.LoadFrom("DB.dll");
                Type type0 = assembly0.GetType("DB.Person");
                object objec = Activator.CreateInstance(type0)!;
                foreach (var item in type0.GetProperties())
                {
    
    
                    if (item.Name.Equals("ID"))
                    {
    
    
                        item.SetValue(objec, 598);
                    }
                    else if (item.Name.Equals("Name"))
                    {
    
    
                        item.SetValue(objec, "SQ");
                    }
                    else if (item.Name.Equals("Age"))
                    {
    
    
                        item.SetValue(objec, 120);
                    }
                }
                //循环获取对应属性的值
                foreach (var prop in type0.GetProperties())
                {
    
    
                    Console.WriteLine($"people.{
      
      prop.Name}={
      
      prop.GetValue(objec)}");
                }
                Console.WriteLine("-----反射方式字段赋值、取值------");
                var fileds = type0.GetFields(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);
                foreach (var item in fileds)
                {
    
    
                    if (item.Name.Equals("Describe"))
                    {
    
    
                        item.SetValue(objec,"描述。。。");
                    }
                }
                foreach (var item in fileds)
                {
    
    
                    if(item.Name.Equals("Describe"))
                    {
    
    
                        Console.WriteLine(item.GetValue(objec));
                    }
                }
            }
            #endregion

        }
        ///根据完整程序集路径获取Assembly对象
        public static void TestAssemly_Path()
        {
    
    
            //1.转换方式一:使用dynamic
            string fullpath = @"C:\Users\DELL\source\repos\SD\DB\bin\Debug\DB.dll";
            Assembly assembly = Assembly.LoadFrom(fullpath);
            Type type = assembly.GetType("DB.DBHelper");
            dynamic instance = Activator.CreateInstance(type!)!;
            var result = instance.Query(100);
            Console.WriteLine(result);

            //转换方式二:使用实现类的接口进行强制转换
            string fullpath1 = @"C:\Users\DELL\source\repos\SD\DB1\bin\Debug\DB1.dll";
            Assembly assembly1 = Assembly.LoadFrom(fullpath1);
            Type type1 = assembly1.GetType("DB1.Sqlserver");
            var instance1 = (ISqlserver)Activator.CreateInstance(type1!)!;
            instance1.Connect();
            instance1.Excute();




        }
        /// <summary>
        ///   //转换方式三:使用命名空间获取Assembly对象
        /// </summary>
        public static void TestAssemly_NameS()
        {
    
    
            //当前程序bin目录下去掉.dll后缀文件
            Assembly assembly2 = Assembly.Load("DB");
            Type type2 = assembly2.GetType("DB.DBHelper");
            var instance2 = (DBHelper)Activator.CreateInstance(type2!)!;  
            var result = instance2.Query(100);
            Console.WriteLine(result);
        }

        #endregion
        static void Main(string[] args)
        {
    
    
            TestAssemly();

            TestAssemly_Path();

            TestAssemly_NameS();
            Console.ReadKey();
        }

猜你喜欢

转载自blog.csdn.net/weixin_45496521/article/details/127955753