C#中的Attribute详解(上)

C#中的Attribute详解(上)

  • 一、Attribute是什么
  • 二、Attribute的作用
  • 三、Attribute与注释的区别
  • 四、系统Attribute范例
    • 1、如果不使用Attribute,为了区分这四类静态方法,我们只能通过注释来说明,但这样做会给系统带来很多垃圾信息,而且不利于测试。注释区分法如下:
    • 2、如果使用Attribute,区分这四类静态方法将会简单许多。当类Program和类ToolKit都在Program.cs文件中时,#define Buged只需要在Program.cs文件头部定义,示例代码如下:
  • 五、系统Attribute范例分析

一、Attribute是什么

Attribute是一种可由用户自有定义的修饰符(Modifier),可以用来修饰各种需要被修饰的目标,修饰符(比如private、public、static、override、virtual等等)是C#语言本身的关键字。
简单地说,Attribute就是一种“附着物”——就像牡蛎吸附在船底或礁石上一样。
这些附着物的作用是为它们的附着体追加上一些额外的信息(这些信息保存在附着物的体内)——比如“这个类是我写的”或者“这个函数以前出过问题”等等。

二、Attribute的作用

Attribute的作用是为元数据添加内容。
元数据可以被工具支持,比如:编译器用元数据来辅助编译,调试器用元数据来调试程序。

三、Attribute与注释的区别

注释是对程序源代码的一种说明,主要目的是给人看的,在程序被编译的时候会被编译器所丢弃,因此,它丝毫不会影响到程序的执行。
Attribute是程序代码的一部分,它不但不会被编译器丢弃,而且还会被编译器编译进程序集(Assembly)的元数据(Metadata)里。在程序运行的时候,你随时可以从元数据中提取提取出这些附加信息,并以之决策程序的运行。

四、系统Attribute范例

在项目中,某个类由两个程序员(小张和小李)共同维护。这个类起到了“工具包”(Utilities)的作用,里面包含几十个静态方法,就像.Net Framework中的Math类一样。这些静态方法,一半是小张写的、一半是小李写的;在项目的测试中,有一些静态方法曾经出过bug,后来又被修正。
我们可以把这些方法分成这样几类:

在这里插入图片描述
我们分类的目的主要是在测试的时候可以按照不同的类别进行测试、获取不同的效果。比如:统计两个人的工作量或者对曾经出过bug的方法进行回归测试。

1、如果不使用Attribute,为了区分这四类静态方法,我们只能通过注释来说明,但这样做会给系统带来很多垃圾信息,而且不利于测试。注释区分法如下:

public static void Li_Buged_FuncA(){ }
public static void Li_NoBug_FuncB(){ }
public static void Zhang_Buged_FuncC(){ }
public static void Zhang_NoBug_FuncD(){ }//或//Created by Li,Buged
public static void FuncA(){ }
//Created by Li,NoBug
public static void FuncB(){ }
//Created by Zhang,Buged
public static void FuncC(){ }
//Created by Zhang,NoBug
public static void FuncD(){ }

2、如果使用Attribute,区分这四类静态方法将会简单许多。当类Program和类ToolKit都在Program.cs文件中时,#define Buged只需要在Program.cs文件头部定义,示例代码如下:

#define Buged //C#的宏定义必须在所有代码之前。当前只让Buged宏有效
//#define NoBug
//#define Li
//#define Zhang
using System;
using System.Diagnostics;//注意:ConditionalAttribute特性包含在此命名空间中namespace AttributeTest
{class Program{static void Main(string[] args){ToolKit.FuncA();ToolKit.FuncB();ToolKit.FuncC();ToolKit.FuncD();Console.ReadKey();}}public class ToolKit{[ConditionalAttribute("Li")]//Attribute名称的长记法[ConditionalAttribute("Buged")]public static void FuncA(){Console.WriteLine("Created by Li, Buged");}[Conditional("Li")]//Attribute名称的短记法[Conditional("NoBug")]public static void FuncB(){Console.WriteLine("Created by Li, NoBug");}[Conditional("Zhang")][Conditional("Buged")]public static void FuncC(){Console.WriteLine("Created by Zhang, Buged");}[Conditional("Zhang")][Conditional("NoBug")]public static void FuncD(){Console.WriteLine("Created by Zhang, NoBug");}}
}

当类Program在Program.cs文件中,类ToolKit在ToolKit.cs文件中时,#define Buged需要在Program.cs文件头部和ToolKit.cs文件头部均定义,示例代码如下:

#define Buged //C#的宏定义必须在所有代码之前。当前只让Buged宏有效
//#define NoBug
//#define Li
//#define Zhang
using System;
using System.Diagnostics;
namespace AttributeTest
{class Program{static void Main(string[] args){ToolKit.FuncA();ToolKit.FuncB();ToolKit.FuncC();ToolKit.FuncD();Console.ReadKey();}}
}#define Buged //C#的宏定义必须在所有代码之前。当前只让Buged宏有效
//#define NoBug
//#define Li
//#define Zhang
using System;
using System.Diagnostics;
namespace AttributeTest
{public class ToolKit{[Conditional("Li")][Conditional("Buged")]public static void FuncA(){Console.WriteLine("Created by Li, Buged");}[Conditional("Li")][Conditional("NoBug")]public static void FuncB(){Console.WriteLine("Created by Li, NoBug");}[Conditional("Zhang")][Conditional("Buged")]public static void FuncC(){Console.WriteLine("Created by Zhang, Buged");}[Conditional("Zhang")][Conditional("NoBug")]public static void FuncD(){Console.WriteLine("Created by Zhang, NoBug");}}
}

运行结果如下:
注意:运行结果是由代码中“#define Buged ”这个宏定义所决定。
在这里插入图片描述

五、系统Attribute范例分析

1、在本例中,我们使用了ConditionalAttribute这个Attribute,它被包含在System.Diagnostics命名空间中,多半时间是用来做程序调试与诊断的。
2、与ConditionalAttribute相关的是一组C#宏,它们看起来与C语言的宏别无二致,位置必须在所有C#代码之前。顾名思义,ConditionalAttribute是用来判断条件的,凡被ConditionalAttribute(或Conditional)”附着”了的方法,只有满足了条件才会执行。
3、就像船底上可以附着很多牡蛎一样,一个方法上也可以附着多个ConditionalAttribute的实例。把Attribute附着在目标上的书写格式很简单,使用方括号把Attribute括起来,然后紧接着写Attribute的附着体即可。当多个Attribute附着在同一个目标上时,就把这些Attribute的方括号一个挨一个地书写(或者在一对方括号中书写多个Attribute),而且不必在乎它们的顺序。
4、在使用Attribute的时候,有“长记法”和“短记法”两种。

由上面的第三条和第四条我们可以推出,以下四种Attribute的使用方式完全等价:

//长记法
[ConditionalAttribute("Li")]
[ConditionalAttribute("NoBug")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//短记法
[Conditional("Li")]
[Conditional("NoBug")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//换序
[Conditional("NoBug")]
[Conditional("Li")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }
//单括号叠加
[Conditional("NoBug"),Conditional("Li")]
public static void Func()
{Console.WriteLine("Created by Li, NoBug"); }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/307088.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT】QStringListModel类的应用介绍

目录 1 概述 2 QStringListModel常用方法 3 使用QStringListModel的步骤 4 QStringListModel的使用 4.1 Model/View结构对象和组件初始化 4.2 编辑、添加、删除项的操作 4.3 以文本显示数据模型的内容 4.4 其他功能 1 概述 QStringListModel用于处理字符串列表的数据模型…

VSCode安装Go环境

VSCode安装Go 1.点击Go官网,根据自己环境下载go安装包,我这里为Windows 2.双击安装包,一直点击【Next】即可 VSCode配置Go基础环境 1.创建Go的工作目录: C:\Code\GoCode 2.创建Go的环境变量: GOPATH (1)右键【此电脑】,点击…

2024年第四届电气、电子与信息工程国际会议(ISEEIE 2024) | Ei&Scopus双检索

会议简介 Brief Introduction 2024年第四届电气、电子与信息工程国际会议(ISEEIE 2024) 会议时间:2024年9月26日-28日 召开地点:英国莱斯特(Leicester, UK) 大会官网:www.iseeie.org 2024年第四届电气、电子与信息工程…

器件的静态特性

器件的静态特性 静态特性(伏安特性) 1.器件在导通或关断的状态下,其电压与电流对应关系。 2.静态过程体现器件最基本的电压与电流稳态特性。 动态特性(开关特性) 1.器件在开或关过程中,其电压、电流随时…

7.7复原IP地址(LC93-M)

算法: 根据题意 有效的 IP 地址 : (1)由四个整数构成 (2)每个整数位于 0 到 255 之间 (3)每个整数不能含有前导 0,如011、021等,但是可以有单独的一个“…

使用Jenkins和单个模板部署多个Kubernetes组件

前言 在持续集成和部署中,我们通常需要部署多个实例或组件到Kubernetes集群中。通过Jenkins的管道脚本,我们可以自动化这个过程。在本文中,我将演示如何使用Jenkins Pipeline及单个YAML模板文件(.tpl)来部署多个类似的…

Android Studio 如何实现软件英文变中文教程

目录 前言 一、确认版本号 二、下载汉化包 三、汉化包安装 四、如何实现中英文切换 五、更多资源 前言 Android Studio是一款功能强大的集成开发环境(IDE),用于开发Android应用程序。默认情况下,Android Studio的界面和…

使用云渲染节省成本与提升渲染速度的秘诀

我们在提交效果图到云渲染平台时,有时会因为各种原因,如不小心设置错了参数,导致渲染时间变长,渲染费用增加。这不仅增加了项目的成本,还可能影响到整个项目的进度。面对这一问题,炫云提供了小光子、保守优…

【数据结构和算法】---二叉树(2)--堆的实现和应用

目录 一、堆的概念及结构二、堆结构的实现2.1堆向下调整算法2.2堆向上调整算法2.3删除堆顶元素2.4插入元素2.5其他函数接口 三、堆结构的应用3.1堆排序3.2Top-k问题 四、堆概念及结构相关题目 一、堆的概念及结构 如果有一个数字集合,并把它的所有元素按完全二叉树…

最新微信投票平台系统源码 一键创建各种投票活动 盈利模式强大

随着社交媒体的普及,微信已经成为人们日常生活中不可或缺的一部分。而微信投票平台源码,作为一种基于微信平台的投票工具,以其简单易用、功能强大的特点,在各种活动和竞赛中被广泛应用。今天给大家分享一款可商用的微信投票平台系…

Lunix的奇妙冒险————权限篇

文章目录 一.什么是权限二.用户权限和类别。1.用户2.角色3.更换文件角色 三.文件的类别和对应权限1.文件的类别。2.文件属性权限1.权限说明。2.默认生成文件权限来源3.更改权限 3.文件的执行与删除 四.不同用户共同在一个目录下的权限。1.普通用户家目录2.在同一目录下文件的权…

文本的剪切和复制有区别吗?有什么区别

在电脑操作中,文本的剪切与复制是我们经常进行的操作。尽管它们看起来都是对文本的“复制”行为,但两者在使用和功能上存在明显的差异。本文将详细介绍剪切与复制的区别,以帮助您更好地理解它们的适用场景和作用,并介绍剪切后如何…