反射(type和assembly)
这里简要介绍type和assembly
自定义特性
为了理解编写自定义特性的方式,应了解一下在编译器遇到代码中某个应用自定义特性的元素时,该如何处理。
[AttributeUsage(AttributeTargets.Property,AllowMultiple =false,Inherited =false)]
public class FieldNameAttribute:Attribute
{
public string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}
[FieldName("text")]
public string text { get; set; }
这段代码中定义一个FieldNameAttribute的类。当C#编译器发现这个属性(text)应用了一个FieldName特性时,首先会把字符串Attribute追加到这个名称的后面,然后在其搜索路径的所有名称空间中搜索有指定名称的类。但要注意,如果用一个特性标记数据项,而该特性的名称以字符串Atribute结尾,编译器就不会把该字符串加到组合名称中,而是不修改该特性名。
[FieldName("text")]
public string text { get; set; }
等价于
[FieldNameAttribute("text")]
public string text { get; set; }
1、AttributeUsage
要注意的第一个问题是特性类本身用一个特性--System.AttributeUsage特性来标记。这是Microsoft定义的一个特性,C#编译器为它提供了特殊的支持。AttributeUsage主要用于标记自定义特性应用到哪些类型的程序元素上。这些信息由它的第一个参数给出,该参数是必选的,其类型是枚举类型AttributeTarget。在上面的示例中,指定FieldName特性只能应用到属性上。AttributeTarget枚举的成员如下:
ALL Assembly Class Constructor Delegate Enum GenericParameter Interface Method Module Parameter Property Return Value Struct
这个列表列出了可以应用该特性的所有程序元素。注意在把特性应用到程序元素上时,应把特性放在元素前面的方括号中。但是,在上面的列表中,有两个值不对任何程序元素:Assembly Module。 特性可以应用到整个程序集或模块中,而不是应用到代码中的一个元素上,在这种情况下,整个特性可以放在源代码中的任何地方,但需要关键字Assembly或Module作为前缀:
[Assembly:SomeAssemblyAttribute(Parameters)]
[Module:SomeAssemblyAttribute(Parameters)]
在指定自定义特性的有效目标元素时,可以使用按位OR运算符把这些值组合起来。例如:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Method,AllowMultiple =false,Inherited =false)]
public class FieldNameAttribute:Attribute
{
public string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}
也可以使用AttributeTargets.All指定特性可以应用到所有类型的程序元素上。AttributeUsage还包含另外两个参数:AllowMultiple和Inherited。它们用不同的语法来指定:
= 。这些参数是可选的,根据需要自己判断。
AllowMultiple参数表示一个特性是否可以多次应用到同一项上。Inherited参数设置为true,就表示应用到类或接口上的特性也可以应用到所有派生的类或接口上。
2、指定特性参数
编译器会检查传递给特性的参数,并查找该特性中带这些参数的构造函数。找到此构造函数,反射会从程序集中读取元数据(特性),并实例化他们表示的特性类。因此,需要确存在这样的构造函数,不然编译错误。
3、指定特性的可选参数
在AttributeUsage特性中,可以使用另一种语法,把可选参数添加到特性中。这种语法指定可选参数的名称和值,它通过特性类中的公共属性或字段起作用。
[FieldName("text", comment="12542231")]
public string text { get; set; }
public class FieldNameAttribute:Attribute
{
public string comment;
public string Comment { get { return comment; } set { comment = value; } }
.........
}
编译器识别第二个参数的语法,并且不会把这个参数传递给FieldNameAttribute类的构造函数,而是查找一个有该名称的公共属性或字段。
反射
通过System.Type类可以访问关于任何数据类型的信息。我们以前把Type看作一个类,实际上它是一个抽象的基类。只要实例化一个Type对象,实际上就是实例化了Type的一个派生类。尽管一般情况下派生类只提供各种Type方法和属性的不同重载,但是这些方法和属性返回对应数据类型的正确数据,Type有与每种数据类型对应的派生类。他们一般不添加新的方法或属性。通常有三种方式:
a、使用c#的typeof运算符:Typet=typeof(double);
b、使用GetType()方法,所有的类都会从System.object继承这个方法。
c、还可以调用Type类的静态方法GetType()
Type的属性:
Type的属性可以分为三类:首先,许多属性都可以获取包含与类相关的各种名称的字符串,如:Name、FullName、Namespace. 其次,属性还可以进一步获取Type对象的引用,这些引用表示相关的类。如:BaseType、UnderlyingSystemType。 还有一类就是许多的布尔属性表示这种类型是一个类还是一个枚举等。这些特性包括:IsAbstract、IsArray、IsClass、IsEnum、IsInterface、IsPointer、IsPrimitive、IsPublic、IsSeadled、IsValueType.
Type的方法:
System.Type的大多数方法都用于获取对应数据类型的成员信息:构造函数、属性、方法和事件等。他有许多方法,但他们都有相同的模式。例如:GetMethod()和GetMethods()。
Assembly类
Assembly类它允许访问给定程序集的元数据,它也包含可以加载和执行程序集的方法。在使用Assembly实例做一些工作前,需要把相应的程序集加载到正在允许的进程中。为此,可以使用静态成员Assembly。Load()或Assembly.LoadFrom()。这两个方法的区别是Load()方法的参数是程序集的名称,运行库会在各个位置上搜索该程序集,试图找到该程序集,这些目录包括本地目录和全局程序集缓存。而LoadFrom()方法的参数是程序集完整路径名,他不会在其他位置搜索该程序集:
Assembly assemblys1 = Assembly.Load("textassembly");
Assembly assemblys2 = Assembly.LoadFrom(@"C:\My Project\textassembly");
1、获取在程序集中定义的类型的详细信息
Assembly 类的一个功能是它可以获得在相应程序集中定义的所有类型的详细信息,只要调用Assembly.GetType()方法,他就可以返回一个包含所有类型的详细信息的System.Type引用数组,就可以按照Type处理的方式引用了。
2、获取自定义特性的详细信息
用于查找在程序集或类型中定义了什么自定义特性的方法取决于与该特性相关的对像类型。Attribute[] aa = Attribute.GetCustomAttributes(assemblys2);
************这是相当重要的,以前你可能想知道,在定义自定义特性时,为什么必须费尽周折为他们编写类,以及为什么没有更简单的语法。答案就在于此,自定义特性确实与对象一样,加载了程序集后,就可以读取这些特性对象,查看它们的属性,调用他们的方法。**************
GetCustomAttributes()方法用于获取程序集的特性,它有两个重载方法:第一个参数是程序集的引用,第二个参数是Type对象。
Attribute[] aa = Attribute.GetCustomAttributes(assemblys2,typeof(FieldNameAttribute));
反射(type和assembly)的更多相关文章
- 反射+type类+Assembly+特性
什么是元数据,什么是反射: 程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据. 有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程 ...
- 【Unity|C#】基础篇(12)——反射(Reflection)(核心类:Type、Assembly)
[学习资料] <C#图解教程>(第24章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...
- 反射 type 的基本用法,动态加载插件
这里介绍反射的简单实用 MyClass类 public class MyClass { public int Age { get; set; } public string Name { get; s ...
- C# 反射 Type.GetType()
对于外部调用的动态库应用反射时要用到Assembly.LoadFile(),然后才是获取类型.执行方法等;当用反射创建当前程序集中对象实例或执行某个类下静态方法时只需通过Type.GetType(&q ...
- .NET反射 Type类
不知道大家有过这样类似的编码 ? 1 Type type=typeof(T);//T是传入的类型 这样写已经是在潜意思的使用反射了.不管你是否知道,但是这是事实. Type是一个抽象类,必须进行实例化 ...
- 详解反射->Type.System
反射先了解 一:system.Type 获取基本信息: Type.Name //类名 Type.FullName //完整路径 Type.Namespace //空间名 public class ...
- C#中反射type记录
写代码的时候经常需要使用反射相关的东西例如:分析现有类型自动生成类, 或者为现有的类自动增加一些功能总结了一点点经验以ClassA a; 为例1. 通过typeof(ClassA) 或者 a.Get ...
- .Net反射-Type类型扩展
/// <summary> /// Type 拓展 /// </summary> public static class TypeExtensions { /// <su ...
- C# 反射 Type.GetFields 方法
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Reflecti ...
随机推荐
- 流畅python学习笔记第十八章:使用asyncio包处理并发(一)
首先是线程与协程的对比.在文中作者通过一个实例分别采用线程实现和asynchio包实现来比较两者的差别.在多线程的样例中,会用到join的方法,下面来介绍下join方法的使用. 知识点一:当一个进程启 ...
- imagick图片压缩。
选择一个合适的图片处理扩展包. 常见的扩展如GD,imagick,Gmagick. 老古董的GD丢掉吧,效率很低,而且压缩的图片体积很大=.= imagick是个不错的选择,在PHP的图片处理扩展 ...
- PHP生成图片太慢了。。有些都不出来、
现在为了使用不同宽高的图片,做了个动态生成的程序.每次根据图片传入的宽高来输出图片,然后 html 页面里用 <img src="xxx.com/img?src=c8d997dae15 ...
- could not read symbols: Archive has no index;
could not read symbols: Archive has no index; run ranlib to add one collect2: ld returned 1 exit sta ...
- CentOS 7 设置自定义开机启动,添加自定义系统服务
详细文档,http://www.linuxidc.com/Linux/2015-04/115937.htm 摘自: http://www.centoscn.com/CentOS/config/2015 ...
- laravel基础课程---13、数据库基本操作2(lavarel数据库操作和tp对比)
laravel基础课程---13.数据库基本操作2(lavarel数据库操作和tp对比) 一.总结 一句话总结: 非常非常接近:也是分为两大类,原生SQL 和 数据库链式操作 学习方法:使用时 多看手 ...
- codeforces 658C C. Bear and Forgotten Tree 3(tree+乱搞)
题目链接: C. Bear and Forgotten Tree 3 time limit per test 2 seconds memory limit per test 256 megabytes ...
- 《java编程思想》:第五章,初始化与清理
知识点整理: 1.从概念上讲,‘初始化’与‘创建’是彼此独立的,但是在Java中,两者被捆绑在一起,不可分离. 2.区分重载的方法:每个重载的方法都有一个独一无二的参数类型列表. 甚至参数顺序的不同也 ...
- dd备份文件系统
1.实现dd的备份: 使用gzip压缩: dd if=/dev/hdb | gzip > /local/path/image.gz 说明:/dev/hdb 是硬盘整盘.对不同的硬盘,可能是 /d ...
- Early Media and Music on Hold
Early media refers to any media that is played to the initial caller’s phone before the remote party ...