定制Attribute

时间:2023-02-18 08:44:18

目录

  • Attribute是什么
  • 自定义Attribute

一、Attribute是什么

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

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

 [Flags]
public enum Options
{
None=,
Insert = , //二进制: 0001
Update = , //二进制: 0010
Save = , //二进制: 0100
Delete = , //二进制: 1000
Query = //二进制:10000
}

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

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

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

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

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

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

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

我们同样F12看一下定义:

public sealed class DllImportAttribute : Attribute
{
public bool BestFitMapping; public CharSet CharSet; public DllImportAttribute(string dllName); public CallingConvention CallingConvention;
public string EntryPoint;
public bool ExactSpelling;
public bool PreserveSig;
public bool SetLastError;
public bool ThrowOnUnmappableChar;
public string Value { get; }
}

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

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

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

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

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

3、多个Attribute组合

 [Flags]
[DllImport("Json.Text", CharSet = CharSet.Auto, BestFitMapping = true)]
public enum Options
{
None=,
Insert = , //二进制: 0001
Update = , //二进制: 0010
Save = , //二进制: 0100
Delete = , //二进制: 1000
Query = //二进制:10000
}

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

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

二、自定义Attribute

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

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

 [System.AttributeUsage(System.AttributeTargets.Class |System.AttributeTargets.Struct,
AllowMultiple = true,
Inherited = true
)]
public class MarkAttribute : System.Attribute
{
public string appname;
public double version = 1.0; public MarkAttribute(string appname)
{
this.appname = appname;
}
}

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

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

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

 [Mark("Apple", version = 2.0)]
public class APP
{
}

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

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

 System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(MarkAttribute));  // Reflection.

            foreach (System.Attribute attr in attrs)
{
if (attr is MarkAttribute)
{
MarkAttribute m = (MarkAttribute)attr;
System.Console.WriteLine(" {0}, 版本 {1:f}",m.appname,m.version);
}
}

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

但是编译器是如何调用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. 打字机游戏Ⅱ之手速pk

    前言 demo预览->typewriter gameⅡ (chrome only 没做兼容) 别看一开始时速度不快,会线性增长的哦,反正楼主的score还没达到过40... 为什么叫Ⅱ呢?之前写 ...

  2. Mac相关命令

    1,查询端口占用与Kill相应进程 lsof -i:端口,查询端口的占用情况 kill PID,关闭指定PID的进程. 如: localhost:~ tianjingcheng$ kill 729 l ...

  3. win8系统开发者预览版安装中文软件报错怎么办

    相信大家看到这边博客时,应该也是遇到类似的问题,这个可能是win8的一个bug.最直接的解决方法是,将目前语言环境由中文改为英文,再安装运行软件应该就不会有问题了. 但是,我们下次在安装应用程序时依然 ...

  4. C++类包含问题(重复包含和相互包含)

    一.重复包含头文件 头文件重复包含,可能会导致的错误包括:变量重定义,类型重定义及其他一些莫名其妙的错误.C++提供两种解决方案,分别是#ifndef和#pragma once #ifndef _SO ...

  5. NYNU_省赛选拔题(10)

    题目描述 Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recog ...

  6. Zernike不变矩

    1.Zernike矩介绍 Zernike矩是基于 Zernike多项式的正交化函数,所利用的正交多项式集是 1个在单位圆内的完备正交集.Zernike矩是复数矩 ,一般把 Zernike矩的模作为特征 ...

  7. Xcode 10 正在编辑时 闪退

    1.Xcode 10 正在编辑时 闪退 好在Xcode做了很好的及时保存机制和现场恢复措施,就算突然闪退,重新打开Xcode 还能看到之前的代码. 可以让Xcode的工程编译设置恢复成Xcode 之前 ...

  8. NPM升级

    nmp的更新可以使用自身指令即可: npm install npm -g 可以看到从3.10.10升级到了4.0.5 都说npm比node升级的快,现在比起来nodejs的更新速度更快 如果npm官方 ...

  9. django之runserver命令分析

    def inner_run(self, *args, **options):#runserver命令执行的内容 # If an exception was silenced in Management ...

  10. ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置

    ASP.NET Web API的路由和ASP.NET MVC相似,也是把路由放在RouteTable中的.可以在App_Start文件夹中的WebApiConfig.cs中设置路由模版.默认的路由模版 ...