这里简要介绍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. Swift 学习笔记 (类和结构体)

    类和结构体是一种多功能且灵活的构造体.通过使用与现存常量 变量 函数完全相同的语法来在类和结构体中定义属性和方法以添加功能. Swift中不需要你为自定义的类和结构体创建独立的结构和实现文件.在Swi ...

  2. HTML 学习笔记 JQuery(盒子操作)

    这边博客详细的讲述一下JQuery中关于盒子模型的一些方法 offset([coordinates])方法 获取匹配元素在当前适口的相对偏移 返回的对象包含两个模型属性:top和left 以像素计.此 ...

  3. Android笔记之ViewModel的使用示例

    依赖 implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'com.squareup.retrofit2:r ...

  4. Linux安装mariadb详细步骤

    1.安装mariadb yum和源码编译安装的区别? 1.路径区别-yum安装的软件是他自定义的,源码安装的软件./configure --preifx=软件安装的绝对路径 2.yum仓库的软件,版本 ...

  5. NinjaFramework中文教程(简单版)-手把手教程-从零开始

    第一步: 官网http://www.ninjaframework.org/documentation/getting_started/create_your_first_application.htm ...

  6. Java for LeetCode 111 Minimum Depth of Binary Tree

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  7. SPOJ - GSS1 —— 线段树 (结点信息合并)

    题目链接:https://vjudge.net/problem/SPOJ-GSS1 GSS1 - Can you answer these queries I #tree You are given ...

  8. join()方法作用

    当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1 废话不多说看代码: package com.toov5.thread; public class JoinThreadT ...

  9. 同级别中枢重叠后的走势分类---walkspeed

    同级别走势的中枢震荡有重叠,即意味当下级别走势类型是不能延续啦.走势级别开始升级.根据走势分解定理,可知走势能划分出至少三段当下级别的走势类型. 有三段同级别完成的走势类型,就必须有三个同级别的中枢. ...

  10. Linux bash shell环境变量以及语法规范

    摘自: http://blog.csdn.net/abc_ii/article/details/8762739