C#基础精华08(反射,程序集)
什么是程序集?
程序集是.net中的概念。
.net中的dll与exe文件都是程序集。(exe与dll的区别?)
程序集(Assembly),可以看做是一堆相关类打一个包,相当于java中的jar包(*)。
程序集包含:类型元数据(描述在代码中定义的每一类型和成员,二进制形式)、程序集元数据(程序集清单、版本号、名称等)、IL代码(这些都被装在exe或dll中)、资源文件。每个程序集都有自己的名称、版本等信息。这些信息可以通过AssemblyInfo.cs文件来自己定义。
使用程序集的好处?
程序中只引用必须的程序集,减小程序的尺寸。
程序集可以封装一些代码,只提供必要的访问接口。
如何添加程序集的引用?
添加路径、项目引用、GAC(全局程序集缓存)
不能循环添加引用
在c#中添加其他语言编写的dll文件的引用。(参考P/Invoke,在.net中调用非程序集的dll)extern
反射
反射:就是动态获取程序集中的元数据来操作类型的。
Type类实现反射的一个重要的类,通过它我们可以获取类中的所有信息包括方法、属性等。可以动态调用类的属性、方法。 Type是对类的描述。如何获取Person类中的所有属性?
反射就是直接通过.dll来创建对象,调用成员。
先通过一个普通类介绍Type.(Person)
通过类型元数据来获取对象的一些相关信息,并且还可以实例化对象调用方法等,这个就叫做“反射”。
反射让创建对象的方式发生了改变。
编译器的智能提示就是反射的一个应用。
反射:简单的理解就是通过类型元数据创建对象、调用对象的成员等。
Type类
Type类的使用
通过类获得Type:Type t = typeof(Person)
通过对象获得类的Type:Type t = p.GetType()
“c:\abc.dll”
Assembly asm=Assembly.LoadFile(“c:\abc.dll”);
调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型。
调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型。
调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息。
插件:扩展主程序功能的dll.
Type type=typeof(Person);//没对象
Type ty = per.GetType();//有对象
//获取所有的字段属性
// FieldInfo[]fileinfo= ty.GetFields();
//获取所有的公共属性
PropertyInfo[]propertyin= ty.GetProperties();
//获取所有的方法
MethodInfo[]methinfo= ty.GetMethods();
//获取所有的事件
EventInfo[]eventinfo= ty.GetEvents();
//获取所有的成员
MemberInfo[]member= type.GetMembers();
===================================================================================
Assembly asm= Assembly.LoadFile(@"E:\基础加强1006\01练习题\MyClassLibrary\bin\Debug\MyClassLibrary.dll");
Type[]types1= asm.GetExportedTypes();//获取所有公共的
Type[] types2 = asm.GetTypes();//获得所有的
foreach (Type item in types1)
{
Console.WriteLine(item.Name);
}
Console.ReadKey();
============================================================
foreach (MethodInfo item in methinfo)
{
//没有获取私有方法
Console.WriteLine(item.Name);
}
============================
//Type t = typeof(Person);
////类的全名称
//Console.WriteLine(t.FullName);
////类所在的程序集的全名称
//Console.WriteLine(t.Assembly.FullName);
////获取程序集中所有公共的类型
//Type[] types = ass.GetExportedTypes();
//foreach (Type type in types)
//{
// Console.WriteLine(type.Name);
//}
////获取程序集中所有的类型
//Type[] tys = ass.GetTypes();
//foreach (Type item in tys)
//{
// Console.WriteLine(item.Name);
//}
////根据名称获得一个类型
//Type tPerson = ass.GetType("抽象类.Circle");
//Console.WriteLine(tPerson.Name);
=======================================
Type ty= asm.GetType("MyClassLibrary.Person");
动态创建对象
Activator.CreateInstance(Type t)会动态调用类的无参构造函数创建一个对象,返回值就是创建的对象,如果类没有无参构造函数就会报错。
GetConstructor(参数列表);//这个是找到带参数的构造函数。
Type类的方法:在编写调用插件的程序时,需要做一系列验证。
bool IsAssignableFrom(Type c):(直译:是否可以从c赋值)判断当前的类型的变量是不是可以接受c类型变量的赋值。
typeof(IPlugin).IsAssignableFrom(t)
bool IsInstanceOfType(object o):判断对象o是否是当前类的实例(当前类可以是o的类、父类、接口)
bool IsSubclassOf(Type c):判断当前类是否是类c的子类。类的事,没有接口的事。
IsAbstract,判断是否为抽象的,含接口
Assembly ass= Assembly.LoadFile(@"E:\讲课视频代码集合\备课资料演示\C#基础加强\二次测试代码\01测试代码上\MyProgramClass\bin\Debug\MyProgramClass.dll");
============================================
//获取公用的类
Type[]types= ass.GetExportedTypes();
foreach (Type item in types)
{
Console.WriteLine(item.Name);
}
================================
//获取所有类型
//Type []types= ass.GetTypes();
//foreach (Type item in types)
//{
// Console.WriteLine(item.Name);
//}
=================================================
//获取指定类型的Person
Type typePerson= ass.GetType("MyProgramClass.Person");
Console.WriteLine(typePerson.Name);
============================================================================第一个方法验证
//判断chinese类型是否可以赋值给person
Console.WriteLine(typePerson.IsAssignableFrom(typeChinese));
Console.WriteLine(tyPer.IsAssignableFrom(tyChinese));//括号里的对象能不能赋值给tyPer
=============================================================
Type typePerson = ass.GetType("MyProgramClass.Person");
Type typeChinese = ass.GetType("MyProgramClass.Chinese");
Object chinese= Activator.CreateInstance(typeChinese);
Object person= Activator.CreateInstance(typePerson);
//判断chinese这种类型是不是chinese这种类型
Console.WriteLine(typeChinese.IsInstanceOfType(chinese));
=======================================================================================第二个方法验证
Type tyPer = asm.GetType("MyClassLibrary.Person");
Type tyChinese = asm.GetType("MyClassLibrary.Chinese");
object objPer = Activator.CreateInstance(tyPer);
object objChinese = Activator.CreateInstance(tyChinese);
Console.WriteLine(tyPer.IsInstanceOfType(objChinese));
========================================================
Type typePerson = ass.GetType("MyProgramClass.Person");
Type typeChinese = ass.GetType("MyProgramClass.Chinese");
//判断是不是子类关系,接口没有子类一说,
Console.WriteLine(typePerson.IsSubclassOf(typeChinese));
Console.WriteLine(tyChinese.IsSubclassOf(tyPer));判断chinese是不是Person的子类
==============================================
//判断是不是抽象类含接口,不能实例化的,静态的
Console.WriteLine(typePerson.IsAbstract);
Console.WriteLine(tyPer.IsAbstract);
Console.WriteLine(tyIfly.IsAbstract);
=========================================是不是抽象的
==============================================
反射调用方法:
namespace _02反射调用方法
{
class Program
{
static void Main(string[] args)
{
Type tp = typeof (Person);
//方法
MethodInfo mt = tp.GetMethod("SayHello");
object p= Activator.CreateInstance(tp);//创建Person对象
mt.Invoke(p,null);//调用了SayHello方法
}
}
public class Person
{
public void SayHello()
{
Console.WriteLine("你好啊");
}
}
}
动态调用成员
MemberInfo类 抽象类,有很多子类,下面讲的类都继承自它,获取程序集成员的相关信息(类型、方法、事件、字段和属性)
PropertyInfo获取属性
主要成员:CanRead、CanWrite、PropertyType属性类型;SetValue、GetValue:读取值,设置值,第一个参数是实例对象,因为set、get要针对具体实例,最后一个参数null。pInfo.SetValue(p1, 30, null)
MethodInfo获取方法
MethodInfo都是和具体对象不相关的,所以需要第一个参数指定要执行的对象。
FieldInfo获取字段
EventInfo获取事件
C#基础精华08(反射,程序集)的更多相关文章
- iOS系列 基础篇 08 文本与键盘
iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...
- Linux基础精华
Linux基础精华 (继续跟新中...) 常用命令: Linux shell 环境 让你提升命令行效 率的 Bash 快捷键 [完整版] 设置你自己的liux alias Linux的Find使用 L ...
- C#基础知识回顾-- 反射(3)
C#基础知识回顾-- 反射(3) 获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺垫, ...
- C#基础知识回顾-- 反射(1)
C#基础知识回顾-- 反射(1) 反射(reflection)是一种允许用户获得类型信息的C#特性.术语“反射”源自于它的工作方式: Type对象映射它所代表的底层对象.对Type对象进行查询可以 ...
- 黑马程序猿————Java基础日常笔记---反射与正則表達式
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 黑马程序猿----Java基础日常笔记---反射与正則表達式 1.1反射 反射的理解和作用: 首 ...
- C#程序集系列08,设置程序集版本
区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...
- Java基础13:反射与注解详解
Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...
- Java基础教程:反射基础
Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...
- Linux基础精华(转)
Linux基础精华 (继续跟新中...) 常用命令: Linux shell 环境 让你提升命令行效 率的 Bash 快捷键 [完整版] 设置你自己的liux alias Linux的Find使用 L ...
随机推荐
- TCP HelloWord
client.cpp #include <stdio.h> #include <winsock2.h> #pragma comment (lib,"ws2_32&qu ...
- apk反编译之二——smali学习
在apk被反编译后,原来的java程序会以smali文件呈现.这就需要补充smali的知识.依旧参考官方文档,择日我将把官方文档做一下翻译.今日先贴出链接地址: 1:了解smali字节码的寄存器 请参 ...
- python: 生成guid
其实经常需要生成一个guid,在各种场合使用...也简单写个小脚本实现吧. 实现下来发现速度比较慢... import uuid import sys def show_ver(): print 'g ...
- Python开发【第一篇】Python基础之装饰器
写代码要遵循开发封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已实现的功能代码块开放:对扩展开发 #s2 ...
- Docs list
http://www.deansys.com/doc/ldd3/index.html Github中文文档: http://www.worldhello.net/gotgithub/03-projec ...
- 正确处理WPF中Slider值改变事件的方式
最近在用WPF数据绑定重写一下播放器项目时遇到的关于Slider的问题,在窗体透明度调节和播放进度调节上用了Slider控件.调节窗体透明度我是 这么想的:将窗体的Opacity属性的值与Slider ...
- JDBC ----常用数据库的驱动程序及JDBC URL:
常用数据库的驱动程序及JDBC URL: Oracle数据库: 驱动程序包名:ojdbc14.jar 驱动类的名字:oracle.jdbc.driver.OracleDriver JDBC URL ...
- c++中new分配动态数组
变长一维数组 这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组.实现变长数组最简单的是变长一维数组,你可以这样做: //文件名: array01.cpp ...
- ssh-keygen实现免密码登陆
在 Client 端建立 Public 与 Private Key : 建立的方法真的是简单到不行!直接在 192.168.0.100 这个 Client 上面,以 test2 这个账号,使用 ssh ...
- VBS基础篇 - 堆栈
VBS中的堆栈需要使用System.Collections.Stack '建立堆栈 Dim Stk : Set Stk = CreateObject("System.Collections. ...