C# 反射

什么是反射

在这里插入图片描述

IL: 也是一种面向对象语言,但是不太好阅读
metadata元数据:数据清单,描述了DLL/exe里面的各种信息
反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库 ,可以读取并使用metadata

反射的几种功能及实现

动态加载程序并创建对象

namespace Reflection.DB.MySql
{
    public class MySqlHelper : IDBHelper
    {
        public MySqlHelper()
        {
            //GetType获取当前实例的 Type。
            //Name获取当前成员的名称。
            Console.WriteLine($"{this.GetType().Name}被构造");
        }
        public void Query()
        {
            Console.WriteLine($"{this.GetType().Name}.query");
        }
    }
}

  #region 动态加载程序并创建对象
                {
                    //动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
                    Assembly assembly = Assembly.Load("Reflection.DB.MySql");
                    //完整路径(全路径+文件后缀)
                    Assembly assembly1 = Assembly.LoadFile(@"C:\Users\Lenovo\Source\Repos\Csharp高级编程\MyReflectionProject\bin\Debug\netcoreapp3.1\Reflection.DB.MySql.dll");
                    //当前路径 (默认在当前路径查找 Dll全名称+后缀)
                    Assembly assembly2 = Assembly.LoadFrom("Reflection.DB.MySql.dll");
                    //路径同assembly1
                    Assembly assembly3 = Assembly.LoadFile(@"C:\Users\Lenovo\Source\Repos\Csharp高级编程\MyReflectionProject\bin\Debug\netcoreapp3.1\Reflection.DB.MySql.dll");

                    foreach (var type in assembly.GetTypes())
                    {
                        Console.WriteLine(type.Name);
                    }

                }
                {
                    //1. 动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
                    Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
                    //2. 获取程序集中指定的类型,路径是全名称(命名空间+类名)
                    Type type = assembly.GetType("Reflection.DB.SqlServer.SqlServerHelper");
                    //3. 根据类型创建对象
                    object objSqlServer = Activator.CreateInstance(type);
                    //dynamic dSqlhelper = Activator.CreateInstance(type);  //动态类型不安全
                    // dSqlhelper.Query();
                    //dSqlhelper.show();  不安全,避开编译器的检查 

                    //4. 类型转换
                    IDBHelper dBHelper = objSqlServer as IDBHelper;
                    //5. 调用方法
                    dBHelper.Query();

                }
                //工厂方法进行包装
                {
                    IDBHelper dBHelper = SimpleFactory.CreateInstace();
                }
                #endregion




    public class SimpleFactory
    {
        private static string IDBHelperConfig="Reflection.DB.SqlServer";
        private static string DllName = "Reflection.DB.SqlServer";
        private static string TypeName = "Reflection.DB.SqlServer.SqlServerHelper";

        public static IDBHelper CreateInstace()
        {
            //1. 动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
            Assembly assembly = Assembly.Load(DllName);
            //2. 获取程序集中指定的类型,路径是全名称(命名空间+类名)
            Type type = assembly.GetType(TypeName);
            //3. 根据类型创建对象
            object objSqlServer = Activator.CreateInstance(type);
            //dynamic dSqlhelper = Activator.CreateInstance(type);  //动态类型不安全
            // dSqlhelper.Query();
            //dSqlhelper.show();  不安全,避开编译器的检查 

            //4. 类型转换
            IDBHelper dBHelper = objSqlServer as IDBHelper;
            //5. 调用方法
            return dBHelper;
        }
    }

反射破坏单例 调用私有构造函数

  /// <summary>
    /// 单例模式:类,能保证在整个进程中只有一个实例
    /// </summary>
    public  sealed class Singleton
    {
        private static Singleton _Singleton = null;
        private Singleton()
        {
            Console.WriteLine("Singleton被构造");
        }
        static Singleton()
        {
            _Singleton = new Singleton();
        }
        public static Singleton GetInstance()
        {
            return _Singleton;
        }
    }
Singleton singleton = Singleton.GetInstance();
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
Console.WriteLine(object.ReferenceEquals(singleton, singleton1));  //返回true,表示是为单例 

Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
Type type = assembly.GetType("Reflection.DB.SqlServer.Singleton");
Singleton oSingleto = (Singleton)Activator.CreateInstance(type, true);  //第二个参数为true可以访问私有的方法
Singleton oSingleto1 = (Singleton)Activator.CreateInstance(type, true);
Console.WriteLine(object.ReferenceEquals(oSingleto, oSingleto1));  //返回false

反射调用方法

Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
Type type = assembly.GetType("Reflection.DB.SqlServer.ReflectionTest");
object oReflectionTest = Activator.CreateInstance(type, true); //创建对象

// public void Show1()  无参
MethodInfo methodShow1 = type.GetMethod("Show1");
methodShow1.Invoke(oReflectionTest, new object[] { });

//  public void Show2(int id)  有参
MethodInfo methodShow2 = type.GetMethod("Show2");
methodShow2.Invoke(oReflectionTest, new object[] { 123 });

//public void Show3(int id,string name)  重载
MethodInfo methodShow3 = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
methodShow3.Invoke(oReflectionTest, new object[] { 123, "zhangsan" });


//  public void Show3(string name, int id)  重载
MethodInfo methodShow3_2 = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
methodShow3_2.Invoke(oReflectionTest, new object[] { "wangwu", 123 });


//private void Show4(string name)  私有方法
MethodInfo methodShow4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
methodShow4.Invoke(oReflectionTest, new object[] { "wangwu" });

// public static void Show5(string name) 静态方法
MethodInfo methodShow5 = type.GetMethod("Show5");
methodShow5.Invoke(oReflectionTest, new object[] { "wangwu" });
methodShow5.Invoke(null, new object[] { "wangwu" });

ReflectionTest

namespace Reflection.DB.SqlServer
{
    /// <summary>
    /// 反射测试类
    /// </summary>
    public class ReflectionTest
    {
        #region Identity
        /// <summary>
        /// 无参数构造函数
        /// </summary>
        public ReflectionTest()
        {
            Console.WriteLine($"这里是{this.GetType()}无参数构造函数");
        }
        /// <summary>
        /// 有参数构造函数
        /// </summary>
        /// <param name="name"></param>
        public ReflectionTest(string name)
        {
            Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
        }
        /// <summary>
        /// 有参数构造函数
        /// </summary>
        /// <param name="id"></param>
        public ReflectionTest(int id)
        {
            Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
        }
        /// <summary>
        /// 多参数构造函数
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        public ReflectionTest(int id,string name)
        {
            Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
        }
        #endregion

        #region Method
        /// <summary>
        /// 无参数方法
        /// </summary>
        public void Show1()
        {
            Console.WriteLine($"这里是{this.GetType()}的show1");
        }
        /// <summary>
        /// 有参数方法
        /// </summary>
        /// <param name="id"></param>
        public void Show2(int id)
        {
            Console.WriteLine($"这里是{this.GetType()}的show2");
        }


        #region show3  重载
        /// <summary>
        /// 重载方法之一
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        public void Show3(int id,string name)
        {
            Console.WriteLine($"这里是{this.GetType()}的show3");
        }
        /// <summary>
        /// 重载方法之二
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        public void Show3(string name,int id)
        {
            Console.WriteLine($"这里是{this.GetType()}的show3_2");
        }
        /// <summary>
        /// 重载方法之三
        /// </summary>
        /// <param name="name"></param>
        /// <param name="id"></param>
        public void Show3( int id)
        {
            Console.WriteLine($"这里是{this.GetType()}的show3_3");
        }
        /// <summary>
        /// 重载方法之四
        /// </summary>
        /// <param name="name"></param>
        public void Show3(string name)
        {
            Console.WriteLine($"这里是{this.GetType()}的show3_4");
        }
        // 重载方法之五
        public void Show3()
        {
            Console.WriteLine($"这里是{this.GetType()}的show3_1");
        }
        #endregion


        /// <summary>
        /// 私有方法
        /// </summary>
        /// <param name="name"></param>
        private void Show4(string name)
        {
            Console.WriteLine($"这里是{this.GetType()}的Show4");
        }
        /// <summary>
        /// 静态方法
        /// </summary>
        /// <param name="name"></param>
        public static void Show5(string name)
        {
            Console.WriteLine($"这里是{typeof(ReflectionTest)}的Show5");
        }
        #endregion
    }
}

反射获取泛型方法

//普通类有泛型方法
Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");


//普通类有泛型方法
{
    Type type = assembly.GetType("Reflection.DB.SqlServer.GenericMethod");
    object oReflectionTest = Activator.CreateInstance(type); //创建对象
    MethodInfo method = type.GetMethod("Show");
    //用类型数组的元素替代当前泛型方法定义的类型参数
    MethodInfo show = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
    show.Invoke(oReflectionTest, new object[] { 123, "zhang", DateTime.Now });
}
//泛型类有泛型方法
{
    Type type = assembly.GetType("Reflection.DB.SqlServer.GenericClass`3");  //`3 表示泛型个数

    //指定创建对象需要的泛型参数
    Type GenericType = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
    //创建对象
    object oReflectionTest = Activator.CreateInstance(GenericType);
    //因为方法的泛型参数在获取类型时已经获取,所以不需要再指定
    MethodInfo method = GenericType.GetMethod("Show");
    //用类型数组的元素替代当前泛型方法定义的类型参数
    method.Invoke(oReflectionTest, new object[] { 123, "zhang", DateTime.Now });
}

//泛型类有泛型方法,并且方法中有使用到类所定义的泛型类型
{
    Type type = assembly.GetType("Reflection.DB.SqlServer.GenericDouble`1"); //`1 表示泛型个数
    //指定创建对象需要的泛型参数
    Type GenericType = type.MakeGenericType(new Type[] { typeof(bool)});
    //创建对象
    object oReflectionTest = Activator.CreateInstance(GenericType);
                       
    MethodInfo method = GenericType.GetMethod("Show");
    //获取方法的泛型参数类型
    MethodInfo show = method.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) });
    show.Invoke(oReflectionTest, new object[] { true, "zhang", DateTime.Now });
}
namespace Reflection.DB.SqlServer
{
    /// <summary>
    /// 泛型类有泛型方法
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="W"></typeparam>
    /// <typeparam name="X"></typeparam>
    public class GenericClass<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}");
        }
    }
    /// <summary>
    /// 普通类有泛型方法
    /// </summary>
    public class GenericMethod
    {
        public void Show<T, 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}");
        }
    }
    /// <summary>
    /// 泛型类有泛型方法,并且方法中有使用到类所定义的泛型类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class GenericDouble<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}");
        }
    }
}

反射获取属性与字段

//反射获取属性与字段
{
    People people = new People
    {
        Id = 123,
        Name = "zH",
        Description = "dy"
    };
    Console.WriteLine($"id={people.Id},name={people.Name},description={people.Description}");
    Type type = typeof(People);
    object oPeople=Activator.CreateInstance(type);
    //设置属性值
    foreach (PropertyInfo prop in type.GetProperties())
    {
        if (prop.Name.Equals("Id"))
        {
            prop.SetValue(oPeople, 456);
        }
        else if (prop.Name.Equals("Name"))
        {
            prop.SetValue(oPeople, "hu");
        }
        Console.WriteLine(prop.GetValue(oPeople));
    }
    //设置字段
    foreach (FieldInfo field in type.GetFields())
    {
        if (field.Name.Equals("Description"))
        {
            field.SetValue(oPeople, "描述信息");
        }
    }
    //获取属性
    foreach (PropertyInfo prop in type.GetProperties())
    {
        Console.WriteLine($"oPeople.{prop.Name}={prop.GetValue(oPeople)}");
    }
    //获取字段
    foreach (FieldInfo field in type.GetFields())
    {
        Console.WriteLine($"oPeople.{field.Name}={field.GetValue(oPeople)}");
    }
}
namespace Reflection.Model
{
    public class People
    {
        public People()
        {
            Console.WriteLine($"{this.GetType().FullName}被创建");
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值