目录

  • Attribute是什么
  • 自定义Attribute

一、Attribute是什么

将一些附加信息与制定目标相关联的方式。编译器在元数据中生成这些额外的信息。也叫做特性。

比如之前文章中提到的:枚举类型与位运算。也是向枚举类型定制了[FlagsAtribute]特性,将枚举类型作为一个位标识集合使用。

  1. [Flags]
  2. public enum Options
  3. {
  4. None=,
  5. Insert = , //二进制: 0001
  6. Update = , //二进制: 0010
  7. Save = , //二进制: 0100
  8. Delete = , //二进制: 1000
  9. Query = //二进制:10000
  10. }

Attribute使用[]进行标记说明,会在某个目标元素的上方,这里的Flags是FlagsAttribute的简写。

1、那我们F12看一下[Falags]的定义:

  1. public class FlagsAttribute : Attribute
  2. {
  3. // 摘要:
  4. // 初始化 System.FlagsAttribute 类的新实例。
  5. public FlagsAttribute();
  6. }

FlagsAttribute直接或者间接继承自Attribute。当然我们也可以看出所说的Flags特性就是一个类的实例。既然是类的实例,需要有构造方法,所以我们也就看到了上面的构造函数FlagsAttribute。

我们写的[Falags]实际是调用了public FlagsAttribute();构造函数。

2、那我们再来一个例子,先不管这句话什么意思,或者作用是什么。

  1. [DllImport("Json.Text", CharSet = CharSet.Auto,BestFitMapping=true)]
  2. public void GetNewMail(string from, string to, string msg)
  3. {
  4. MailInfo newmailinfo = new MailInfo(from, to, msg);
  5. OnNewMail(newmailinfo);
  6.  
  7. }

我们同样F12看一下定义:

  1. public sealed class DllImportAttribute : Attribute
  2. {
  3. public bool BestFitMapping;
  4.  
  5. public CharSet CharSet;
  6.  
  7. public DllImportAttribute(string dllName);
  8.  
  9. public CallingConvention CallingConvention;
  10. public string EntryPoint;
  11. public bool ExactSpelling;
  12. public bool PreserveSig;
  13. public bool SetLastError;
  14. public bool ThrowOnUnmappableChar;
  15. public string Value { get; }
  16. }

但是这里的构造函数是接受一个String类型的参数,但是我们调用时却是这样写

  1. [DllImport("Json.Text", CharSet = CharSet.Auto,BestFitMapping=true)]

这里的第一个参数是狗咱好书默认的参数,而后面的是DllImportAttribute类中的公共属性或者公共字段,那就不难理解我们这里直接调用了里面的两个公共属性并给他们做了赋值。

那就不难理解这些为什么会这样写了:

  1. [Table("Menu", Schema = "admin")]

3、多个Attribute组合

  1. [Flags]
  2. [DllImport("Json.Text", CharSet = CharSet.Auto, BestFitMapping = true)]
  3. public enum Options
  4. {
  5. None=,
  6. Insert = , //二进制: 0001
  7. Update = , //二进制: 0010
  8. Save = , //二进制: 0100
  9. Delete = , //二进制: 1000
  10. Query = //二进制:10000
  11. }

我们也可以这样写,两个特性用,分隔:

  1. [Flags, DllImport("Json.Text", CharSet = CharSet.Auto, BestFitMapping = true)]

二、自定义Attribute

如何根据需求定义我们自己的特性,通过以上的了解,我们至少知道我们的Attribute直接或者间接继承基类Attribute,并且要有实例构造函数进行构造。也可以定义一些需要的公共属性等等。

当然命名也要符合约定以Attribute为后缀。

  1. [System.AttributeUsage(System.AttributeTargets.Class |System.AttributeTargets.Struct,
  2. AllowMultiple = true,
  3. Inherited = true
  4. )]
  5. public class MarkAttribute : System.Attribute
  6. {
  7. public string appname;
  8. public double version = 1.0;
  9.  
  10. public MarkAttribute(string appname)
  11. {
  12. this.appname = appname;
  13. }
  14. }

我们定义一个MarkAttribute,我们约定我们自定义的特性符合AttributeUsage特性:目标元素为类或者结构,允许多个属性,可以继承。

我们自己定义的MarkAttribute,有两个公共字段appname和version。并有一个构造函数。

这样我们这样运用自己的简单的特性:

  1. [Mark("Apple", version = 2.0)]
  2. public class APP
  3. {
  4. }

既然定义了,也标注到了特定的目标上,剩下的就是我们调用了。

通过反射来调用我们定义的特性:

  1. System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(MarkAttribute)); // Reflection.
  2.  
  3. foreach (System.Attribute attr in attrs)
  4. {
  5. if (attr is MarkAttribute)
  6. {
  7. MarkAttribute m = (MarkAttribute)attr;
  8. System.Console.WriteLine(" {0}, 版本 {1:f}",m.appname,m.version);
  9. }
  10. }

这样我们就完成了我们自定义的特性并完成调用。

但是编译器是如何调用Attribute的呢?

编译器检测到一个元素应用到一个元素应用到attribute的时候,编译器会调用attribute类的构造器,向他传递参数,就构造了一个实例,

编译器再根据特定的语法对公共字段和属性进行初始化,并将这些信息驻留到元数据中。这只是会生成相关的元数据。

那编译器又是如何调用特性的呢?

和我们上面的例子类似,通过反射。我们知道所有的特性都继承自Attribute,我们F12转到定义可以看到,基类Attribute主要有三组方法组成:

GetCustomAttribute:返回应用的一个特性.

GetCustomAttributes:返回应用的多个特性.

IsDefined:检测判断元素是否应用Attribute.

总结,我们知道什么是Attribute,并可以自定义Attribute.

定制Attribute的更多相关文章

  1. C# 定制 Attribute 简单使用

    所谓 “定制Attribute”,就是一个类的实例,它被序列化成驻留在元数据的一个字节流. 我们可以使用 Attribute 来保存注释: namespace AttributeDemo { [Att ...

  2. [Clr via C#读书笔记]Cp18 定制Attribute

    Cp18 定制Attribute 意义 利用Attribute,可以声明性的给自己的代码结构创建注解,从而实现一些特殊的功能:最终在元数据中生成,这种可扩展的元数据信息可以在运行时的时候查询,从而动态 ...

  3. C#提高------------------------Attribute自定制概念

    C#基础知识梳理系列八:定制特性Attribute   摘 要 设计类型的时候可以使用各种成员来描述该类型的信息,但有时候我们可能不太愿意将一些附加信息放到类的内部,因为这样,可能会给类型本身的信息描 ...

  4. Attribute

    Attribute介绍 咱们来说Attribute,他是一个类,所以自定义的Attribute都是继承自System.Attribute,一般命名的时候都是以Attribute结尾.在使用的时候我们可 ...

  5. 有关C#标签Attribute的熟悉

    Attribute 简单用法: 最近用到了,所以静下心来找些资料看了一下,终于把这东西搞清楚了. 一.什么是Attribute 先看下面的三段代码: 1.自定义Attribute类:VersionAt ...

  6. [CLR via C#]18. Attribute

    attribute可以说是Microsoft .NET Framework提出的最具创意的技术之一了.利用attribute,可以声明性的为自己的代码构造添加注解,从而实现一些特殊的功能.attrib ...

  7. C# Attribute 特性 学习

    一.特性的概述 公共语言运行库允许您添加类似关键字的描述性声明(称为特性 (Attribute))来批注编程元素,如类型.字段.方法和属性 (Property).属性与 Microsoft .NET ...

  8. .Net Attribute特性

    1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述: 公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标 ...

  9. 读书笔记—CLR via C#委托和attribute

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

随机推荐

  1. windows phone 获取手机图片库中图片(4)

    原文:windows phone 获取手机图片库中图片(4) 前置条件:手机和电脑未连接或连接电脑Zune软件关闭(与Zune软件连接时不允许访问图片库): 版本7.1 获取手机图片库图片的两种方式: ...

  2. 设计模式10---设计模式之原型模式(Prototype)

    1.场景模式 考虑这样一个实际应用:订单处理系统 里面有一个保存订单的功能,当产品数量超过1000份以后,拆成两份订单,再超,那么就再拆.直到每份订单不超过1000为止,订单有两种,一个是个人订单,一 ...

  3. cocos2d-x V3.0 呼叫加速度计 Acceleration

    今天克服了一个问题,我觉得非常酷 哈哈. 今天得到解决cocos2d-x 3.0 呼叫重力加速器问题,上网查了很多资料 发现是不够,不解决这个问题,我不知道如果我使用3.0 这一问题的版本号,但是,这 ...

  4. android studio学习

    http://blog.csdn.net/ryantang03/article/details/8948037 http://www.it165.net/pro/html/201109/676.htm ...

  5. jQuery来源学习笔记:扩展的实用功能

    // 扩展的实用功能 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控 ...

  6. 令人无限遐想的各种PCIe加速板卡

    声明 本文不涉及不论什么特定API,也不针对不论什么特定的厂商,可是仍然值得透露一点的是,某些加速板卡厂商的成功点和失败点恰恰都是在于其通用性,在这个人们依旧依赖专业板卡的时代,依旧将板卡视为解决专业 ...

  7. Cocos2d-x学习笔记(五岁以下儿童) 精灵两种方式播放动画

     这几天在看控件类,临时没有想好实际运用的方向.单纯的创建网上已经有非常多这方面的样例,我就不写了.接下来是学习精灵类.精灵类若是单独学习也是非常easy.于是我加了一些有关动画方面的知识点与精灵 ...

  8. Codeforces Round #257 (Div. 2) D题:Jzzhu and Cities 删特殊边的最短路

    D. Jzzhu and Cities time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. Threejs 它可以在建立其内部房间效果可见

    Threejs 中建立可看到其内部的房间效果 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协 ...

  10. Xamarin.Android 在VS下调试时提示 In mgmain JNI_OnLoad 程序“Mono”已退出 解决办法

    原因是使用了破解版的 Xamarin,调试时不能使用共享库