C#--反射,操作类库Dll文件(简单)

反射就是使用System.Reflection命名空间下的方法来操作DLL文件。

使用方法及步骤:

一、加载Dll文件

方式一:使用Assembly.Load

这个文件要放在启动项目Debug目录下(例如:E:\ App\bin\Debug),也可以通过添加引用的方式添加。

Assembly assembly1=Assembly.Load("DLL文件的名称");//不用加.后面的扩展名

方式二:使用Assembly.LoadFile

使用完整路径,例如:E:\ App\bin\Debug\XXX.dll

Assembly assembly2=Assembly.LoadFile(@"DLL文件的完整路径");

(常用)方式三:使用Assembly.LoadFrom

使用完整路径 或者 DLL文件的名称+扩展名,前两种的结合,一般用这种

Assembly assembly3=Assembly.LoadFrom(@"DLL文件的完整路径 或者 DLL文件的名称+扩展名");                    

二、如果不知道DLL文件中有哪些类型

可以通过遍历获取所有的类型名称

        foreach(var item in assembly)//查找所有的类型
        {
            Console.WriteLine(item.Name);  //打印类型的名字     
        }

三、获取指定类型

假设我们知道要获取的类型是 "Namespace.ClassName"(命名空间+类名)

Type type = assembly3.GetType("Namespace.ClassName");

四、获取指定类型中的构造方法和参数

          //BindingFlags.Instance|BindingFlags.NonPubli是根据想要获取的方法的类型添加标签,这里是获取私有的构造方法
         foreach(var ctor in type.GetConstructors(BindingFlags.Instance|BindingFlags.NonPublic))//
        {
            Console.WriteLine($"构造方法:{ctor.Name}");  // 获取构造方法,因为构造方法名字和类名一样,这里只会打印一个点
            
              //获取构造方法的参数  
              foreach(var param in ctor.GetParameters)
              {
                   Console.WriteLine($"构造方法参数:{param.ParameterType}");  // 获取构造方法参数             
              }
        }

五、创建类型的实例

           创建类型的实例,因为返回值是object类型,所用object来接
                第一种:构造方法没有参数
                object instance = Activator.CreateInstance(type);//动态实例化
                第二种:构造方法有参数
                object instance = Activator.CreateInstance(type,new object[] { 参数1, 参数2 });//动态实例化
                第三种:调用私有无参数数构造函数,添加标签
                object instance = Activator.CreateInstance(
                                type,
                                BindingFlags.Instance | BindingFlags.NonPublic,
                                null,
                                new object[] { },
                                null
                            );
                第四种:调用私有有参数数构造函数,添加标签
                object instance = Activator.CreateInstance(
                            type,
                            BindingFlags.Instance | BindingFlags.NonPublic,
                            null,
                            new object[] { 参数1, 参数2 },
                            null
                        );      
                            

六、调用类型的公开方法

调用普通方法,用.加方法名就可以了,比如有一个Show1的普通方法

 //调用方法前需要将instance转换为具体的类,使用as不报错,转换失败返回空,也可用其它方式
 ClassName feflectionTest=instance as ClassName;//(具体类名+新名字=原名 as 具体类名)                
 feflectionTest.Show1();

七、调用类型的私有方法

                 //【*】调用私有方法
                    //已经知道了方法的名字J叫Show2,然后通过名字找到这个方法
                    //不能用instance和feflectionTest,要用最开始的type
                    //添加查找标签:实例的|不公开的
                    var method=typ.GetMethod("Show2",BindingFlags.Instance|BindingFlags.NonPublic);
                    //调用方法
                    //没有参数{}中就不填,
                    //参数数组 new object[]{ 42, "Hello", 3.14 } 
                    //中的每个元素对应方法的一个参数,顺序必须与方法定义中的参数顺序一致。
                    method.Invoke(instance,new object[]{});//instance在上面第五项中定义

八、调用类型的泛型方法

可以使用第六项,调用公开方法的方式调用,也可以使用以下这种

//假如知道方法的名字叫Show3
//按名字找到方法
var method = type.GetMethod("Show3");//查找指定的类型
var genericMethod=method.MakeGenericMethod(new Type[]{typeof(int)});//指定泛型参数类型T
genericMethod.Invoke(instance,new object[]{参数1, 参数2});//instance在上面第五项中定义

九、泛型类+泛型方法

1.加载DLL文件
Assembly assembly=Assembly.LoadFrom(@"DLL文件的完整路径或者DLL文件的名称+扩展名");  
2.获取指定泛型类,例如在SqlServerDB命名空间下有一个GenericClass<T,W>类
Type type=assembly.GetType("SqlServerDB.GenericClass`2").MakeGenericType(type(int),type(string));
解释:"SqlServerDB.GenericClass`2"中"`2"的意思是有两个参数<T,W>,有几个参数就是几,type(int),type(string)是用来指定这两个参数的。

3.实例化类
object objTest=Activator.CreateInstance(type);
 
4.方法调用,假如有一个public void GenericMethod<t>();方法
 通过方法名获取方法,并指定t为int
 var method=type.GetMethod("GenericMethod").MakeGenericMethod(typeof(int));
 调用获取到的方法
 method.Invoke(objTest.new object[]{});
         

十、操作属性

定义以下几个属性用做实验

1.加载DLL文件
Assembly assembly=Assembly.LoadFrom(@"DLL文件的完整路径或者DLL文件的名称+扩展名");  
2.获取指定泛型类,例如在SqlServerDB命名空间下有一个PropertyClass类
Type type=assembly.GetType("SqlServerDB.PropertyClass");
3.实例化类
object objTest=Activator.CreateInstance(type);
4.获取所有属性的名称
foreach(var property in type.GetProperties())
{
    Console.WriteLine(property.Name);
    //设置指定名称的属性的值,例如设置ID的值
    if(property.Name.Equals("Id"))//Equals是用来判定是否相等的方法
    {
        property.SetValue(objTest,1);//设置为1    
    }
    else if(property.Name.Equals("Name"))
    {
        property.SetValue(objTest,"小明");    
    }
    else if(property.Name.Equals("Phone"))
    {
        property.SetValue(objTest,"1234567890");    
    }
    
    //获取属性的值
    Console.WriteLine(property.GetValue(objTest));
    
}

  • 17
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值