博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原]反射学习整理
阅读量:5992 次
发布时间:2019-06-20

本文共 4491 字,大约阅读时间需要 14 分钟。

 

一、MSDN上面找的学习资料

反射提供了封装程序集、模块和类型的对象( 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。

反射通常具有以下用途:

·   使用 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。

·   使用 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。

·   使用 了解以下信息:构造函数的名称、参数、访问修饰符(如 public private)和实现详细信息(如 abstract virtual)等。使用 方法来调用特定的构造函数。

·   使用 了解以下信息:方法的名称、返回类型、参数、访问修饰符(如 public private)和实现详细信息(如 abstract virtual)等。使用 方法来调用特定的方法。

·   使用 了解以下信息:字段的名称、访问修饰符(如 public private)和实现详细信息(如 static)等;并获取或设置字段值。

·   使用 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。

·   使用 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。

·   使用 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。

·   当您在一个应用程序域的仅反射上下文中工作时,请使用 来了解有关自定义属性的信息。使用 CustomAttributeData,您不必创建属性的实例就可以检查它们。

二、反射的重要应用与相关练习

反射在下列情况下很有用:

·   需要访问程序元数据的属性。

C# 具有一个反射系统,可用来检索用自定义属性定义的信息。主要方法是 GetCustomAttributes,它返回对象数组,这些对象在运行时等效于源代码属性。

下面是我参照MSDN写的一个例子:定义一个自定义属性,将其应用于若干实体并通过反射进行检索。

 1
using
 System;
 2
using
 System.Collections.Generic;
 3
using
 System.Text;
 4
 5
namespace
 Attribut
 6
{
 7    //允许指定多个属性实例,类YaoJian中进行了练习
 8    [AttributeUsage(AttributeTargets.Class,AllowMultiple = true)]
 9    public class Students:Attribute
10    {
11        string name;
12        public int age;
13        
14        public Students(string Name)
15        {
16            name = Name;
17            age = 18;
18        }
19
20        public string GetName()
21        {
22            return name;
23        }
24    }
25    //将自定义属性应用于类
26    [Students("李江")]
27    class LiJiang
28    {
29        //
30    }
31
32    //不定义Students属性
33    class ZhaoYong
34    {
35        //
36    }
37    //应用多个属性实例
38    [Students("姚键"),Students("李云",age = 20)]
39    class YaoJian
40    {
41        //
42    }
43    class Program
44    {
45        static void Main(string[] args)
46        {
47            StudentsInfo(typeof(LiJiang));
48            StudentsInfo(typeof(ZhaoYong));
49            StudentsInfo(typeof(YaoJian));
50        }
51
52        private static void StudentsInfo(Type t)
53        {
54            Console.WriteLine("学生信息是:{0}",t);
55            //获取对象中的自定义属性
56            Attribute[] att = Attribute.GetCustomAttributes(t);
57            foreach (Attribute a in att)
58            {
59                if (a is Students)
60                {
61                    Students S = (Students)a;
62                    Console.WriteLine("学生的姓名是:{0},年龄是:{1}",S.GetName(),S.age.ToString());
63                }
64            }
65        }
66    }
67}
68
运行结果是:
 

·   检查和实例化程序集中的类型。

·   在运行时构建新类型。使用

中的类。

·   执行后期绑定,访问在运行时创建的类型的方法。

三、实践,用反射调用COM

用反射调用COM非常的方便,不需要先对COM进行注册添加引用,用Assembly类中的LoadFrom方法直接可以讲.dll文件加载到程序中,然后对其实例化使用。

实例:

1、先做一个简单的调用系统outlookCOM

先在
VS2005
中建一个
windows
控件库工程,取名为
Send
,然后把控件的界面删掉,在
Send
工程中添加一个
windows
窗体也取名为
Send
,在窗体的
load
事件里面写代码调用
outlook
。完整的代码如下:
 1
using
 System;
 2
using
 System.Collections.Generic;
 3
using
 System.ComponentModel;
 4
using
 System.Data;
 5
using
 System.Drawing;
 6
using
 System.Text;
 7
using
 System.Windows.Forms;
 8
 9
//
使用进程引用命名空间
10
using
 System.Diagnostics;
11
namespace
 Send
12
{
13    public partial class Send : Form
14    {
15        public Send()
16        {
17            InitializeComponent();
18        }
19        /**//// <summary>
20        /// 在Form_Load中调用Windows带的outlook
21        /// </summary>
22        /// <param name="sender"></param>
23        /// <param name="e"></param>
24        private void Send_Load(object sender, EventArgs e)
25        {
26            Process P = new Process();
27            P.StartInfo.FileName = "C:\\Program Files\\Outlook Express\\msimn.exe";
28            P.Start();
29            this.Close();
30        }
31    }
32}
33

代码写完以后,生成一下,这时在工程的bin文件夹下面就生成了一个Send.dll的文件。

2、用反射来调用上面的COM

Send工程的解决方案上面点击右键添加/新建项目/windows应用程序,取名FansheForm1上面添加一个button,并设置其相关属性,界面如图:

把上面生成的Send.dll放到Fanshebin目录下面,在buttonclick事件中添加代码调用COM,完整代码如下:

 1
using
 System;
 2
using
 System.Collections.Generic;
 3
using
 System.ComponentModel;
 4
using
 System.Data;
 5
using
 System.Drawing;
 6
using
 System.Text;
 7
using
 System.Windows.Forms;
 8
 9
//
使用反射引用的命名空间
10
using
 System.Reflection;
11
12
namespace
 Fanshe
13
{
14    public partial class frm : Form
15    {
16        public frm()
17        {
18            InitializeComponent();
19        }
20
21        private void btn_Click(object sender, EventArgs e)
22        {
23            /**//*加载COM,这样写COM的默认路径在bin文件夹下,如果不在可以通过绝对路径或者相对路径指到COM所在的位置
24             *比如:Assembly.LoadFrom("D://App//Send.dll")或Assembly.LoadFrom(".//Send.dll")
25             */
26            Assembly A = Assembly.LoadFrom("Send.dll");
27            //注意参数中,第一个Send是COM中要实例化类的命名空间名,第二个Send是类名
28            Object O = A.CreateInstance("Send.Send");
29            Form F = (Form)O;
30            F.Show();
31        }
32    }
33}
34
代码完成后,将
Fanshe
设为启动项并运行,点击
button
,调出
outlook
,界面如下:
 

这个简单的例子就完成了,里面使用了反射的很少一部分内容,但也可以帮助理解反射机制。

 四、反射的应用要点

1.现实应用程序中很少有应用程序需要使用反射类型 

2.使用反射动态绑定需要牺牲性能 

反射的性能损失主要来源于比较类型、遍历成员、调用成员三种情形,其中比较类型耗时最小,调用成员耗时最多,所以尽量减少采用成员动态调用等反射方式可以提高应用程序性能。除此之外,采取后期绑定、避免将反射方法放到循环内产生放大效应等办法均可提升反射性能。

3.有些元数据信息是不能通过反射获取的 

某些反射类型是专门为那些
clr 
开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。
 程序下载:

转载于:https://www.cnblogs.com/salonliudong/archive/2007/10/10/919719.html

你可能感兴趣的文章
JavaScript新手的第一堂函数课:定义与参数(文末福利)
查看>>
【NetApp】可以使用查设备备件型号的链接
查看>>
【ssi】增删改查六操作小框架(四)
查看>>
Nginx服务整理 优化点
查看>>
linux下查找java进程占用CPU过高原因
查看>>
如何命令破解root 密码
查看>>
Redhat6.9更换yum源
查看>>
KOL的知识变现
查看>>
博科300交换机不中断(non-disruptive)固件升级
查看>>
盘点微信中被隐藏的实用功能
查看>>
tcpdump抓包工具
查看>>
红帽7之hostnamectl 实用小命令用法
查看>>
配置防盗链、访问控制Directory、FiliesMatch
查看>>
Swarm基于多主机容器网络-overlay networks 梳理
查看>>
Linux LVM之VG
查看>>
chkconfig命令学习
查看>>
lvs负载均衡realserver windows配置
查看>>
kettle 使用
查看>>
沫沫金:BootStarp轮播组件(carousel)支持触屏【Hammer】
查看>>
OpenStack入门修炼之网络虚拟化基础(20)
查看>>