最近在项目上用到反射来调用方法用的比较多,传参包含两种方式,一种是通过变量传参,第二种是通过构造函数传参,下面分别介绍下两种方式:

先介绍几种获取实例的方法,下面描述中提到的三种方法其实都是大同小异的,核心就是通过System.Reflection.Assembly 类型的CreateInstance方法创建实例。

//反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间,假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型):

Assembly assembly = Assembly.LoadFile("程序集路径,不能是相对路径"); // 加载程序集(EXE 或 DLL)
object obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例//若要反射当前项目中的类可以为:
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
object obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例,返回为 object 类型,需要强制类型转换//也可以为:
Type type = Type.GetType("类的完全限定名");
object obj = type.Assembly.CreateInstance(type);

那么简单的解释一下这种方法的原理:

1.找到要实例化的类所在的程序集,并将之实例为System.Reflection.Assembly 类的对象

2.利用System.Reflection.Assembly 类提供的CreateInstance方法,创建类的对象

一、通过变量传参

通过变量传参稍微简单点,原理很简单,先通过反射获取到类,这里的类需要有个公共变量,然后将该类从object类型强制转换为原本的类名,比如反射调用的DLL中原本类名是Class1,那么通过反射获取创造该类后强制转换为Class1,这样就可以直接通过实例给类中的变量赋值。(注意:如果是调用外部的DLL,需要先引用该类的程序集)

先创建一个简单类:

public class Class1{private string _strId;public string ID{get { return _strId; }set { _strId = value; }}public Class1(){}public Class1(string str){_strId = str;}}

然后在主函数中加入代码:

Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
object obj = assembly.CreateInstance("ReflectionTest.Test"); //类的完全限定名(即包括命名空间)
Class1 entity = obj as Class1;
entity.ID = "xxxxx";

调试结果:显示obj对象的确不为空,证明这种方法可行。

二、通过构造函数传参

通过构造函数传参稍微复杂,首先修改Class1类,将其构造函数改为:

public Class1(string str)
{_strId = str;
}

假设主函数还是用以前的那样子调用,会直接抛出异常:未找到类型“ReflectionTest.Class1”上的构造函数。这是因为CreateInstance方法默认情况下是通过找无参数的构造函数去创建对象的,现在找不到当然会出错,实时上CreateInstance方法提供了3中签名,其中有CreateInstance(String, Boolean, BindingFlags, Binder, Object [], CultureInfo, Object []) 就可以满足这种情况:

修改主函数如下:

Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
//object obj = assembly.CreateInstance("ReflectionTest.Class1"); //类的完全限定名(即包括命名空间)
object[] parameters = new object[1];
parameters[0] = "test string";
object obj = assembly.CreateInstance("ReflectionTest.Class1",true,System.Reflection.BindingFlags.Default,null,parameters,null,null);// 创建类的实例

测试后运行结果正常

继续加深难度,创建string的对象

首先知道string是System.String的别名,所以要创建的是System.String的对象,而System.String在mscorlib.dll中,所以需要将mscorlib.dll实例为System.Reflection.Assembly的对象,这里利用System.Type类型的属性Assembly来实现功能。

System.String的构造函数有很多种,本文中笔者就不墨迹了,采用String( Char []) 。

最终将主函数中代码改为:

Type type = Type.GetType("System.String");
object[] parameters = new object[1];
char[] lpChar = { 't','e','s','t' };
parameters[0] = lpChar;object obj = type.Assembly.CreateInstance("ReflectionTest.Class1",true,System.Reflection.BindingFlags.Default,null,parameters,null,null);// 创建类的实例 

调试结果:对象为空,失败了,事实上这种方法还有个问题,如将Class1类构造函数修改为

public Test(string str)
{ID = str;//属性赋值
}

调试结果:对象创建成功,但是变量为空

 

解决方案

采用System.Activator 类的CreateInstance方法。

最后见代码:

Type type = Type.GetType("System.String");
object[] parameters = new object[1];
char[] lpCh = { 't', 'e', 's', 't' };
parameters[0] = lpCh;object obj = Activator.CreateInstance(type, parameters);

调试结果:对象创建成功,且变量值正常

采用System.Activator 类的CreateInstance方法,要比System.Reflection.Assembly的CreateInstance简单有效很多。有兴趣的朋友可以仔细看看。

转载于:https://www.cnblogs.com/xiangzhong/p/5391721.html

用反射通过构造函数给窗体传参相关推荐

  1. C#WINFORM窗体传参的最佳实践

    进入VS2005后,大家可以发现子窗体操作父窗体不能沿用2003下的方法:把父窗体的空间访问属性由private改为public.IDE已经把控件声明这部分代码隐藏了,所以只有采用更加对象一点的方法. ...

  2. python 构造函数传参_C++和python混合编程之在python类构造函数中传参方法

    C++和python混合编程 零.前言 一.说明 二.测试代码 1.C++代码 2.python代码 三.运行结果 零.前言 C++是一门高效率的语言,Python是一门简单易学的脚本语言,现在Pyt ...

  3. javascript传值和页面跳转传值(ASP.NET页面传参的三种方法)

    我在csdn上提的问题是        我现在希望从asp.net网页弹出对话框,弹出一些错误信息.警告.提示信息之类的东西,目前准备用javascript实现,所以我希望在调这个对话框的时候,动态传 ...

  4. Vue.js-Day01-PM【事件绑定(事件传参、事件对象、传参+获取事件对象)、样式处理操作(模板、事件、属性绑定)、Tab切换(原生js实现、Vue.js实现)、js中的this详解关键字】

    Vue.js实训[基础理论(5天)+项目实战(5天)]博客汇总表[详细笔记] 目   录 4.事件绑定 4.1.事件绑定(点击.双击.鼠标移动) 点击按钮-最简单的事件绑定(无参函数) 格式 点击按钮 ...

  5. js bind 传参、_js中的面向对象(一)

    面向对象要解决的问题 提到面向对象,大家的第一反应就是封装.继承和多态.对其做如下解释: 封装:影藏细节(A对A--将多行代码取个名字或A对B--API调用合作) 继承:继承的意思就是同上跟上述一样, ...

  6. axios链接带参数_axios常见传参方式

    1:get请求 一般发送请求是这么写 axios.get('/user?id=12345&name=user') .then(function (res) { console.log(res) ...

  7. dynamic结合匿名类型 匿名对象传参

    首先说明下,我一般很少用dynamic关键字(类)的,因为毕竟是由反射实现的,所以对于性能方面还是吃亏不少(注:由于心里没底,查了一些资料得知,dynamic实质上好像不是由反射实现的,其性能也比直接 ...

  8. java导出Excel(POI模式 Ajax下载 Post传参) bootstrap table getVisibleColumns获取显示的列

    工具类 (正式使用) package com.qyj.utils;import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson. ...

  9. react之事件绑定(this、传参)

    一.事件绑定函数中this 默认情况下,this指向undefined import React from 'react' export default class ThingBind extends ...

最新文章

  1. linux磁盘满处理
  2. 转://点评Oracle11g新特性之动态变量窥视
  3. NDK历史版本下载方法
  4. 通过IP获取地址,限制某些地址访问(GeoIp)
  5. redhat搭建NIS服务器
  6. 矩阵的乘法通用模板(C++/Java)
  7. .NET5都来了,你还不知道怎么部署到linux?最全部署方案,总有一款适合你
  8. ThreadLocal知识介绍
  9. winform 窗体中 Time 控件的用法
  10. mysql哪个版本和x86兼容_[C++]C++连接MySQL,封装为class(兼容x86和x64)
  11. 布局:多列等高布局方法
  12. c#控制IE浏览器自动点击等事件WebBrowser,mshtml.IHTMLDocument2 .
  13. MD5在线解密工具推荐
  14. 通过读取原始星历文件数据推算GPS卫星位置坐标
  15. Linux shell脚本文件的各种执行方式
  16. 如何计算机网络打印机,电脑如何连接网络打印机?网络打印机的连接教程
  17. DirectX12(D3D12)基础教程(一)——基础教程
  18. 爆:中国互联网的那些黑色产业链
  19. python怎么变成白色_在python中将一系列颜色更改为白色
  20. 上线群聊功能 阿里搞不赢的社交美团能行吗?

热门文章

  1. 简介struct cmsghdr结构
  2. Typora + PicGo + Gitee
  3. 都2021年了,不会还有人连深度学习都不了解吧(一)- 激活函数篇
  4. Android应用安全之Content Provider安全
  5. 区块链100问 第一问
  6. c执行cmd pdf2swf_PDF2SWF简单使用
  7. JZOJ 5397. 【NOIP2017提高A组模拟10.6】Biology
  8. php manager 怎么用,Windows 2008 R2下如何利用PHPManager对PHP进行配置
  9. Qt5.15 连接MySQL数据库的实现策略
  10. 开发流媒体服务器_Github选出10大开源免费的RTSP流媒体项目