C#反射应用

目录

一、前期准备

二、反射概念

三、反射加载dll方式 

四、反射遍历类

1、遍历dll中的类

2、遍历类中的各种字段

3、遍历类中的各种属性

4、遍历类中的各种方法

五、类中值的应用

1、字段的使用

2、属性的使用

3、方法的使用

1、构造方法 

2、重构方法

3、泛型方法

4、普通方法


涉及知识点: 反射遍历并使用类

一、前期准备

using System;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;

二、反射概念

        通过工程文件中的dll文件,获取并使用内部的类中所有内容

三、反射加载dll方式 

加载一:使用dll文件名

//加载一:使用dll文件名 -- 当前目录 -- 引用->添加引用
  Assembly assembly = Assembly.Load("反射");

加载二:使用完整路径名 

//加载二:使用完整路径名
Assembly assembly = Assembly.LoadFile(@"C:\\Users\\Rush\\Desktop\\C#\\反射\\bin\\Debug\\netcoreapp3.1\\反射.dll");

加载三:使用完全限定名 --(推荐)

//加载三:使用完全限定名 -- 当前目录 -- 引用->添加引用 --(推荐)
Assembly assembly = Assembly.LoadFrom("反射.dll");

加载四:使用完整路径名

 //加载四:使用完整路径名
Assembly assembly = Assembly.LoadFrom(@"C:\\Users\\Rush\\Desktop\\C#\\反射\\bin\\Debug\\netcoreapp3.1\\反射.dll");

四、反射遍历类

1、遍历dll中的类

前期准备:

namespace 反射
{
 internal class Program
 {
   static void Main(string[] args)
    {
    }
 }
 //普通类
 class Student{}
 //泛型类
 class Children<T, K, S>{}
 //接口
 interface ISchool { }
 //秘密类
 sealed class University { }
 //静态类
 static class Company { }
}

 获取dll中类(包括接口):

 GetType("XXX") -- 获取指定类名

 GetTypes()   -- 获取所有类

    internal class Program
    {
        static void Main(string[] args)
        {
            //加载dll
            Assembly assembly = Assembly.LoadFrom("反射.dll");
            //遍历dll 所有类(包括接口)
            foreach (Type type in assembly.GetTypes())
            {
                Console.WriteLine(type.Name);
            }
        }
    }

结果显示: 

2、遍历类中的各种字段

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓字段↓↓↓↓↓↓↓↓
        //内部字段
        internal string name;
        //受保护字段
        protected float grade;
        //静态字段
        public static int age;
        //公开字段
        public int id;
        //私有字段
        private string sex;
    }

 获取类中的各类型字段:

type.GetField("XXX") ; -- 获取指定字段

type.GetFields(); -- 获取所有字段

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //遍历dll 所有类(包括接口)
        foreach (Type type in assembly.GetTypes())
        {
            //显示类名
            Console.WriteLine($"类名:{type.Name}");
            //遍历所有公开字段
            foreach (FieldInfo field in type.GetFields())
            {
                Console.WriteLine($"字段类型:{field.FieldType.Name} " +
                                  $"字段名:{field.Name}");
            }
            //遍历所有私有字段
            foreach (FieldInfo privateField in type.GetFields(BindingFlags.Instance
                                                            | BindingFlags.NonPublic))
            {
                Console.WriteLine($"私有 -- " +
                                  $"字段类型{privateField.FieldType.Name} " +
                                  $"字段名:{privateField.Name}");
            }
        }
    }
}

结果显示: 

3、遍历类中的各种属性

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓属性↓↓↓↓↓↓↓↓
        //内部属性
        internal string Sex { get; set; }
        //受保护属性
        protected int Id { get; set; }
        //公共属性
        public int Age { get; set; }
        //静态属性
        public static float Grade { get; set; }
        //私有属性
        private string Hobby { get; set; }
    }

 获取dll中类(包括接口):

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //遍历dll 所有类(包括接口)
        foreach (Type type in assembly.GetTypes())
        {
            //显示类名
            Console.WriteLine($"类名:{type.Name}");
            //遍历所有公开属性
            foreach (PropertyInfo property in type.GetProperties())
            {
                Console.WriteLine($"属性类型:{property.PropertyType.Name} " +
                                  $"属性名:{property.Name}");
            }
            //遍历所有私有属性
            foreach (PropertyInfo privateField in type.GetProperties(
                               BindingFlags.Instance | BindingFlags.NonPublic))
            {
                Console.WriteLine($"私有 -- " +
                                  $"属性类型{privateField.PropertyType.Name} " +
                                  $"属性名:{privateField.Name}");
            }
        }
    }
}

结果显示: 

4、遍历类中的各种方法

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓构造方法↓↓↓↓↓↓↓↓
        public Student() { }
        internal Student(int id) { }
        protected Student(int id, string sex) { }
        private Student(int id, string sex, float grade) { }
        

        //↓↓↓↓↓↓↓↓重构方法↓↓↓↓↓↓↓↓
        public void Music() { }
        internal void Music(int id) { }
        protected void Music(int id, string name) { }
        private void Music(int id, string name, float grade) { }

        //↓↓↓↓↓↓↓↓泛型方法↓↓↓↓↓↓↓↓
        public void Math<T>() { }
        public void Art<T>(T t) { }

        //↓↓↓↓↓↓↓↓静态方法↓↓↓↓↓↓↓↓
        public static void Chinese() { }

        //↓↓↓↓↓↓↓↓普通方法↓↓↓↓↓↓↓↓
        public int English() => 10;
    }

 获取dll中类(包括接口):

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //遍历dll 所有类(包括接口)
        foreach (Type type in assembly.GetTypes())
        {
            //显示类名
            Console.WriteLine($"类名:{type.Name}");
            //遍历所有公共的方法
            foreach (MethodInfo method in type.GetMethods())
            {
                Console.Write($"方法: {method.ReturnType.Name} " +
                              $"{method.Name}");
                if (method.GetParameters().Length == 0)
                {
                    Console.WriteLine("();");
                    continue;
                }
                foreach (ParameterInfo parameter in method.GetParameters())
                {
                    Console.Write($"({parameter.ParameterType.Name} " +
                                  $"{parameter.Name});");
                }
                Console.WriteLine();
            }
            //遍历所有受保护的方法
            foreach (MethodInfo privateMethod in type.GetMethods(
                                                 BindingFlags.Instance 
                                               | BindingFlags.NonPublic))
            {
                Console.Write($"受保护方法: {privateMethod.ReturnType.Name} " +
                              $"{privateMethod.Name}");
                if (privateMethod.GetParameters().Length == 0)
                {
                    Console.WriteLine("();");
                    continue;
                }
                foreach (ParameterInfo parameter in privateMethod.GetParameters())
                {
                    Console.Write($"({parameter.ParameterType.Name} " +
                                  $"{parameter.Name});");
                }
                Console.WriteLine();
            }
            //遍历所有构造方法
            foreach (ConstructorInfo constructor in type.GetConstructors())
            {
                Console.Write($"构造方法: {constructor.Name}");
                if (constructor.GetParameters().Length == 0)
                {
                    Console.WriteLine("();");
                    continue;
                }
                foreach (ParameterInfo parameter in constructor.GetParameters())
                {
                    Console.Write($"({parameter.ParameterType.Name} " +
                                  $"{parameter.Name});");
                }
                Console.WriteLine();
            }
            //遍历所有受保护的构造方法
            foreach (ConstructorInfo constructor in type.GetConstructors(
                                                         BindingFlags.Instance 
                                                       | BindingFlags.NonPublic))
            {
                Console.Write($"受保护的构造方法: {constructor.Name}");
                if (constructor.GetParameters().Length == 0)
                {
                    Console.WriteLine("();");
                    continue;
                }
                foreach (ParameterInfo parameter in constructor.GetParameters())
                {
                    Console.Write($"({parameter.ParameterType.Name} " +
                                  $"{parameter.Name});");
                }
                Console.WriteLine();
            }
        }
    }
}

结果显示: 

五、类中值的应用

1、字段的使用

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓字段↓↓↓↓↓↓↓↓
        //公共字段
        public int id;
        //静态字段
        public static int age;
        //内部字段
        internal string name;
        //受保护字段
        protected float grade;
        //私有字段
        private string sex;
    }

字段应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        Type studentClass = assembly.GetType("反射.Student");
        object studentObject = Activator.CreateInstance(studentClass);

        //公共字段
        FieldInfo idField = studentClass.GetField("id");
        idField.SetValue(studentObject, 2);
        Console.WriteLine(idField.GetValue(studentObject));

        //公共静态字段
        //!!!设置时: studentObject 可以用 null 代替
        FieldInfo ageField = studentClass.GetField("age");
        ageField.SetValue(null, 3);
        Console.WriteLine(ageField.GetValue(null));

        //-----------------私有字段创建---------------------------
        Type studentPrivateClass = assembly.GetType("反射.Student");
        object studentPrivateObject = Activator.CreateInstance(studentPrivateClass);
            
        //内部字段
        FieldInfo nameField = studentPrivateClass.GetField("name", 
                                                            BindingFlags.Instance 
                                                          | BindingFlags.NonPublic);
        nameField.SetValue(studentPrivateObject, "小王");
        Console.WriteLine(nameField.GetValue(studentPrivateObject));

        //受保护字段
        FieldInfo gradeField = studentPrivateClass.GetField("grade",
                                                             BindingFlags.Instance
                                                           | BindingFlags.NonPublic);
        gradeField.SetValue(studentPrivateObject, 95.6f);
        Console.WriteLine(gradeField.GetValue(studentPrivateObject));

        //私有字段
        FieldInfo sexField = studentPrivateClass.GetField("sex", 
                                                           BindingFlags.Instance
                                                         | BindingFlags.NonPublic);
        sexField.SetValue(studentPrivateObject, "男");
        Console.WriteLine(sexField.GetValue(studentPrivateObject));
    }
}

结果显示:

2、属性的使用

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓属性↓↓↓↓↓↓↓↓
        //公共属性
        public int Id { get; set; }
        //公共静态属性
        public static string Name { get; set; }
        //内部属性
        internal string Sex { get; set; }
        //受保护属性
        protected float Grade { get; set; }
        //私有属性
        private string Hobby { get; set; }
    }

属性应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        Type studentClass = assembly.GetType("反射.Student");
        Object studentObject = Activator.CreateInstance(studentClass);

        //公共属性
        PropertyInfo idProperty = studentClass.GetProperty("Id");
        idProperty.SetValue(studentObject, 2);
        Console.WriteLine(idProperty.GetValue(studentObject));

        //公共静态属性
        //!!!静态时: studentObject 可以用 null 代替
        PropertyInfo nameProperty = studentClass.GetProperty("Name");
        nameProperty.SetValue(null, "小王");
        Console.WriteLine(nameProperty.GetValue(null));

        //-----------------私有字段创建-------------------------- -
        Type studentPrivateClass = assembly.GetType("反射.Student");
        object studentPrivateObject = Activator.CreateInstance(studentPrivateClass);

        //内部属性
        PropertyInfo sexProperty = studentPrivateClass.GetProperty("Sex", 
                                                           BindingFlags.Instance 
                                                         | BindingFlags.NonPublic);
        sexProperty.SetValue(studentPrivateObject, "男");
        Console.WriteLine(sexProperty.GetValue(studentPrivateObject));

        //受保护属性
        PropertyInfo gradeProperty = studentPrivateClass.GetProperty("Grade",
                                                           BindingFlags.Instance
                                                         | BindingFlags.NonPublic);
        gradeProperty.SetValue(studentPrivateObject, 99.6f);
        Console.WriteLine(gradeProperty.GetValue(studentPrivateObject));

        //受私有属性
        PropertyInfo hobbyProperty = studentPrivateClass.GetProperty("Hobby",
                                                           BindingFlags.Instance
                                                         | BindingFlags.NonPublic);
        hobbyProperty.SetValue(studentPrivateObject, "打羽毛球");
        Console.WriteLine(hobbyProperty.GetValue(studentPrivateObject));
    }
}

结果显示:

3、方法的使用

1、构造方法 

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓构造方法↓↓↓↓↓↓↓↓
        public Student() 
            => Console.WriteLine("public 无参构造");
        internal Student(int id) 
            => Console.WriteLine("internal 一个参数构造");
        protected Student(int id, string sex) 
            => Console.WriteLine("protected 两个参数构造");
        private Student(int id, string sex, float grade) 
            => Console.WriteLine("private 三个参数构造");
    }

构造方法应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //获取Student类
        Type studentClass = assembly.GetType("反射.Student");

        //实例化创建Student类
        object studentObject = Activator.CreateInstance(studentClass);
        //public 无参构造
        ConstructorInfo studentConstructor = studentClass
                                            .GetConstructor(Type.EmptyTypes);
        studentConstructor.Invoke(studentObject, null);

        //实例化创建Student类
        object studentObject_1 = Activator.CreateInstance(studentClass, true);
        //internal 一个参数构造
        ConstructorInfo studentConstructor_1 = studentClass
                                              .GetConstructor(
                                               BindingFlags.Instance 
                                             | BindingFlags.NonPublic, null, 
                                               new Type[] { typeof(int) }, null);
        studentConstructor_1.Invoke(new object[] { 2 });

        //实例化创建Student类
        object studentObject_2 = Activator.CreateInstance(studentClass, true);
        //protected 两个参数构造
        ConstructorInfo studentConstructor_2 = studentClass
                                              .GetConstructor(
                                               BindingFlags.Instance 
                                             | BindingFlags.NonPublic, null, 
                                               new Type[] { typeof(int),
                                               typeof(string) }, null);
        studentConstructor_2.Invoke(new object[] { 2, "abc" });

        //实例化创建Student类
        object studentObject_3 = Activator.CreateInstance(studentClass, true);
        //private 三个参数构造
        ConstructorInfo studentConstructor_3 = studentClass
                                              .GetConstructor(
                                               BindingFlags.Instance 
                                             | BindingFlags.NonPublic, null, 
                                               new Type[] { typeof(int),
                                               typeof(string), typeof(float)}, null);
        studentConstructor_3.Invoke(new object[] { 2, "abc", 3.4f });
    }
}

结果显示:

2、重构方法

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓重构方法↓↓↓↓↓↓↓↓
        public void Music() 
                    => Console.WriteLine("public 无参重构");
        internal void Music(int id) 
                    => Console.WriteLine("internal 一个参数重构");
        protected void Music(int id, string sex) 
                    => Console.WriteLine("protected 两个参数重构");
        private void Music(int id, string sex, float grade) 
                    => Console.WriteLine("private 三个参数重构");
    }

重构方法应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //获取Student类
        Type studentClass = assembly.GetType("反射.Student");

        //实例化创建Student类
        object studentObject = Activator.CreateInstance(studentClass);
        //public 无参构造
        MethodInfo MusicMethod = studentClass.GetMethod("Music");
        MusicMethod.Invoke(studentObject, null);

        //internal 一个参构造
        MethodInfo MusicMethod_1 = studentClass.GetMethod("Music",
                                                           BindingFlags.Instance 
                                                         | BindingFlags.NonPublic,
                                                           null, 
                                                         new Type[] { typeof(int)},
                                                           null);
        MusicMethod_1.Invoke( studentObject,new object[] { 2 });

        //protected 两个个参构造
        MethodInfo MusicMethod_2 = studentClass.GetMethod("Music",
                                                           BindingFlags.Instance 
                                                         | BindingFlags.NonPublic,
                                                           null, 
                                          new Type[] { typeof(int), typeof(string) },
                                                           null);
        MusicMethod_2.Invoke(studentObject, new object[] { 2, "abc" });

        //private 三个参构造
        MethodInfo MusicMethod_3 = studentClass.GetMethod("Music",
                                                           BindingFlags.Instance 
                                                         | BindingFlags.NonPublic,
                                                           null, 
                           new Type[] { typeof(int), typeof(string), typeof(float) },
                                                           null);
        MusicMethod_3.Invoke(studentObject, new object[] { 2, "abc", 3.4f });
    }
}

结果显示:

3、泛型方法

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓泛型方法↓↓↓↓↓↓↓↓
        public void Music<T>() => Console.WriteLine("public 无参泛型");
        internal void Art<T>(T id) => Console.WriteLine("internal 一个参数泛型");
        protected void Math<T>(T id) => Console.WriteLine("protected 一个参数泛型");
        private void Chinese<T>(T id) => Console.WriteLine("private 一个参数泛型");
    }

泛型方法应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //获取Student类
        Type studentClass = assembly.GetType("反射.Student");

        //实例化创建Student类
        object studentObject = Activator.CreateInstance(studentClass);

        //public 无参泛型方法
        MethodInfo MusicMethod = studentClass.GetMethod("Music",Type.EmptyTypes);
        MethodInfo Music = MusicMethod.MakeGenericMethod(studentClass);
        Music.Invoke(studentObject, null);

        //internal 一个参数泛型方法
        MethodInfo ArtMethod = studentClass.GetMethod("Art",
                                                       BindingFlags.Instance 
                                                     | BindingFlags.NonPublic);
        MethodInfo Art = ArtMethod.MakeGenericMethod(new Type[] { typeof(int)});
        Art.Invoke(studentObject, new object[] { 2 });


        //protected 一个参数泛型方法
        MethodInfo MathMethod = studentClass.GetMethod("Math", 
                                                        BindingFlags.Instance 
                                                      | BindingFlags.NonPublic);
        MethodInfo Math = MathMethod.MakeGenericMethod(new Type[] { typeof(int) });
        Math.Invoke(studentObject, new object[] { 2 });

        //private 一个参数泛型方法
        MethodInfo ChineseMethod= studentClass.GetMethod("Chinese", 
                                                          BindingFlags.Instance 
                                                        | BindingFlags.NonPublic);
        MethodInfo Chinese = ChineseMethod.MakeGenericMethod(
                                                        new Type[] { typeof(int)});
        Chinese.Invoke(studentObject, new object[] { 2 });
    }
}

结果显示:

4、普通方法

前期准备:

    class Student
    {
        //↓↓↓↓↓↓↓↓普通方法↓↓↓↓↓↓↓↓
        public void Music() => Console.WriteLine("public 无参方法");
        public static int English()
        {
            Console.WriteLine("public static 无参方法");
            return 2;
        }
        internal void Art(int id) => Console.WriteLine("internal 一个参数方法");
        protected void Math(int id) => Console.WriteLine("protected 一个参数方法");
        private void Chinese(int id) => Console.WriteLine("private 一个参数方法");
    }

普通方法应用:

internal class Program
{
    static void Main(string[] args)
    {
        //加载dll
        Assembly assembly = Assembly.LoadFrom("反射.dll");
        //获取Student类
        Type studentClass = assembly.GetType("反射.Student");
        //实例化创建Student类
        object studentObject = Activator.CreateInstance(studentClass);

        //public 无参方法
        MethodInfo MusicMethod = studentClass.GetMethod("Music", Type.EmptyTypes);
        MusicMethod.Invoke(studentObject, null);

        //public static 静态无参方法
        //!!!静态时: studentObject 可以用 null 代替
        MethodInfo EnglishMethod = studentClass.GetMethod("English",
                                                           Type.EmptyTypes);
        Console.WriteLine(EnglishMethod.Invoke(null, null).ToString());

        //internal 一个参数方法
        MethodInfo ArtMethod = studentClass.GetMethod("Art",BindingFlags.Instance 
                                                    | BindingFlags.NonPublic,null,
                                                    new Type[] { typeof(int) },null);
        ArtMethod.Invoke(studentObject, new object[] { 2 });


        //protected 一个参数方法
        MethodInfo MathMethod = studentClass.GetMethod("Math", BindingFlags.Instance
                                                      | BindingFlags.NonPublic, null,
                                                        new Type[] { typeof(int) },
                                                        null);
        MathMethod.Invoke(studentObject, new object[] { 2 });

        //private 一个参数方法
        MethodInfo ChineseMethod = studentClass.GetMethod("Chinese",
                                                           BindingFlags.Instance 
                                                         | BindingFlags.NonPublic,
                                                           null, 
                                                         new Type[] { typeof(int) },
                                                           null);
        ChineseMethod.Invoke(studentObject, new object[] { 2 });
    }
}

结果显示:


如有错误,烦请批评指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值