三 反射 【上】(c#基础学习,上手笔记)

226 阅读2分钟

前序准备,创建几个类库, IDbHelper MysqlHelper SqlHelper 一接口,两实现 ,实现query() 行为,输出

image.png

1 没有反射之前,写死的方法调用。

注意细节,不光using 对应的命名空间,还在要依赖项中,引入类库。

    using Xu;
    IDbHelper dbHelper1 = new MysqlHelper();
    dbHelper1.query();

    IDbHelper dbHelper2 = new SqlserverHelper();
    dbHelper2.query();  

运行效果 image.png

2 反射的what ,how why ?

2.1 什么是反射(what)

官方定义: 反射指程序可以访问、检测和修改它本身状态或行为的一种能力。 (获取读取并使用metadata )

2.2 如何使用。

2.2.1 一个基础实现的例子。
using System.Reflection;

    Console.WriteLine("*********relection*********************************");
    Assembly assembly1 = Assembly.Load("Xu.MysqlHelper"); //加载dll

    Type type = assembly1.GetType("Xu.MysqlHelper");   //获取类型信息

    Console.WriteLine("type:"+type.ToString());
    object oHelper = Activator.CreateInstance(type);  //创对象

    IDbHelper dbHelper3 = (IDbHelper)oHelper; //类型转换

    dbHelper3.query();  //调用。

加载dll > 获取类型信息 > 创对象 > 类型转换 > 调用

意义 唯一的差别,就是用字符串,创建对象并调用了。 (写死与写活的差别)

2.2.2 将上述代码进行封装,调用更简单。 (实现可配置,可扩展)
    /// 创建对象
    /// </summary>
    public class Factory
    {
        public static IDbHelper createHelper()
        {
            Console.WriteLine("*********relection*********************************");
            Assembly assembly1 = Assembly.Load("Xu.MysqlHelper"); //加载dll

            Type type = assembly1.GetType("Xu.MysqlHelper");   //获取类型信息
            Console.WriteLine("type:"+type.ToString());
            object oHelper = Activator.CreateInstance(type);  //创对象
            return  (IDbHelper)oHelper; //类型转换
        }
    }


  IDbHelper dbHelper3 = Factory.createHelper();

这样,只要想办法,去变更那个创建字符串,就实现了,成生oHelper. 常用法方,读配置数据。 进一步的,加载一个新的类库,dll 文件,调整配置,就可以直接用了。

2.2.3 一些特性和用法。
1 破坏单例。

每次createInstance 时,都会调用私有方法构造方法

Singletoe s1 = Activator.CreateInstance(type, true)

2 构造函数存在多个时,

object oHelper = Activotor.CreateInstance(type, new Object[] {123})

3 带泛型时。
   Assembly assembly3 = Assembly.Load("Xu.MysqlHelper"); //加载dll
   Type type = assembly1.GetType("Xu.GenericClas`3");   //搞类型时,要写占位
   
   //确定类型
   Type newType =  type.MakeGenericType(new Type[] {typeof(it), typeof(string), typeof("Datetime")});
   
   object oHelper4 = Activator.CreateInstance(newType);  //创对象
   

2.2.4 反射方法 。

    Assembly as1 = Assembly.Load("Xu.MysqlHelper");

    Type type = as1.GetType("Xu.ReflectTest");

    object oTest = Activator.CreateInstance(type);

    //无参数
    MethodInfo m0 = type.GetMethod("show");
    m0.Invoke(oTest, null);

    MethodInfo m1 = type.GetMethod("show1");
    m1.Invoke(oTest, new object[] { 123});
    
    
    //静态方法调整
    MethodInfo m3 = type.GetMethod("show3");
    m3.Invoke(null, new object[] { "static invode" });
    

拿methodInfo 对象,用Invoke 方法,注意一些语法细节。

函数重载处理

类代码
        public void show4()
        {
            Console.WriteLine("ReflectTest show4 无参数");
        }

        public void show4(int i)
        {
            Console.WriteLine("ReflectTest show4 带int" + i.ToString());
        }
        
     //调用 方法 。
    MethodInfo m4 = type.GetMethod("show4", new Type[]{});
    m4.Invoke(oTest, null);

    MethodInfo m5 = type.GetMethod("show4", new Type[] { typeof(int)});
    m5.Invoke(oTest, new object[] { 123});