这里简要介绍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)的更多相关文章

  1. 反射+type类+Assembly+特性

    什么是元数据,什么是反射: 程序是用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据. 有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程 ...

  2. 【Unity|C#】基础篇(12)——反射(Reflection)(核心类:Type、Assembly)

    [学习资料] <C#图解教程>(第24章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...

  3. 反射 type 的基本用法,动态加载插件

    这里介绍反射的简单实用 MyClass类 public class MyClass { public int Age { get; set; } public string Name { get; s ...

  4. C# 反射 Type.GetType()

    对于外部调用的动态库应用反射时要用到Assembly.LoadFile(),然后才是获取类型.执行方法等;当用反射创建当前程序集中对象实例或执行某个类下静态方法时只需通过Type.GetType(&q ...

  5. .NET反射 Type类

    不知道大家有过这样类似的编码 ? 1 Type type=typeof(T);//T是传入的类型 这样写已经是在潜意思的使用反射了.不管你是否知道,但是这是事实. Type是一个抽象类,必须进行实例化 ...

  6. 详解反射->Type.System

    反射先了解 一:system.Type 获取基本信息: Type.Name   //类名 Type.FullName //完整路径 Type.Namespace //空间名 public class ...

  7. C#中反射type记录

    写代码的时候经常需要使用反射相关的东西例如:分析现有类型自动生成类, 或者为现有的类自动增加一些功能总结了一点点经验以ClassA  a; 为例1. 通过typeof(ClassA) 或者 a.Get ...

  8. .Net反射-Type类型扩展

    /// <summary> /// Type 拓展 /// </summary> public static class TypeExtensions { /// <su ...

  9. C# 反射 Type.GetFields 方法

    using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Reflecti ...

随机推荐

  1. Tomcat学习笔记【4】--- Server.xml配置文件详解

    本文主要讲如何配置Tomcat服务器. 首先展示一个BS结构图: 1 server 一个server就表示一个Tomcat实例. 1)port 指定一个端口,这个端口负责监听关闭tomcat的请求: ...

  2. BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器

    BZOJ3878: [Ahoi2014&Jsoi2014]奇怪的计算器 Description [故事背景] JYY有个奇怪的计算器,有一天这个计算器坏了,JYY希望你能帮助他写 一个程序来模 ...

  3. BCH分叉是一次站队博弈

    BCH分叉在即,很多人说BCH本次分叉实质是大佬间的斗争,主要是本次BCH分叉主要分为两大派别: 一派以BCH用户量最大的客户端Bitcoin ABC开发组为主,要在11月15日展开硬分叉升级,主要升 ...

  4. STO存在哪些潜在隐患?

    STO(Security Token Offering),即证券型通证发行,无疑是现目前区块链圈子讨论最热门的话题之一,纵使STO有很好的前景,但是其潜在隐患也不得不引起重视. 第一,STO与分布式网 ...

  5. nvl()与regexp_replace()

    NVL(字段,0):将空值转化为0 regexp_replace(字段, ‘[1-9]‘ ,'') is not null; 将数字转化为0

  6. ubuntu 更新软件命令

    安装软件最好加权限(sudo) --default-timeout=100 设置超时时间100秒 install -U setuptools 表示更新安装setuptools sudo pip3 -- ...

  7. Android适配API23之后权限的动态申请

    一.权限介绍 对于6.0以下的权限及在安装的时候,根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装,造成了我们想要使用某个app,就要默默忍受其一些不必要的权限(比如是个app都要 ...

  8. Module.exports和exports的区别

    原文链接: https://www.ycjcl.cc/2017/02/10/module-exportshe-exportsde-qu-bie/ 学习Seajs时,看到了exports.doSomet ...

  9. Contiki事件

    一.事件相关数据结构 1.事件结构体 struct event_data { process_event_t ev; process_data_t data; struct process *p; } ...

  10. windows与Linux操作系统的差别

    用户需要记住:Linux和Windows在设计上就存在哲学性的区别.Windows操作系统 倾向于将更多的功能集成到操作系统内部,并将程序与内核相结合:而Linux不同 于Windows,它的内核空间 ...