MSDN 中做如下定义 

Attribute 类将预定义的系统信息或用户定义的自定义信息与目标元素相关联。目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性 (Property)、返回值、结构或其他属性 (Attribute)。

属性所提供的信息也称为元数据。元数据可由应用程序在运行时进行检查以控制程序处理数据的方式,也可以由外部工具在运行前检查以控制应用程序处理或维护自身的方式。例如,.NET Framework 预定义属性类型并使用属性类型控制运行时行为,某些编程语言使用属性类型表示 .NET Framework 公共类型系统不直接支持的语言功能。

所有属性类型都直接或间接地从 Attribute 类派生。属性可应用于任何目标元素;多个属性可应用于同一目标元素;并且属性可由从目标元素派生的元素继承。使用 AttributeTargets 类可以指定属性所应用到的目标元素。

C#中一些默认的预定义属性,见下表:

预定义的属性      有效目标            说明

AttributeUsage;     Class               指定另一个属性类的有效使用方式

CLSCompliant        全部                指出程序元素是否与CLS兼容

Conditional         Method              指出如果没有定义相关联的字符串,编译器可以忽略对这个方法的任何调用

DllImport           Method              指定包含外部方法的实现的DLL位置

STAThread           Method(Main)        指出程序的默认线程模型为STA

MTAThread           Method(Main)        指出程序的默认模型为多线程(MTA)

Obsolete            除了Assembly、Module、Parameter和Return

将一个元素标示为不可用,通知用户此元素将被从未来的产品中移除

ParamArray          Parameter           允许单个参数被隐式地当作params(数组)参数对待

Serializable        Class、Struct、enum、delegate

指定这种类型的所有公共和私有字段可以被串行化

NonSerialized       Field               应用于被标示为可串行化的类的字段,指出这些字段将不可被串行化

StructLayout        Class、struct       指定类或结构的数据布局的性质,比如Auto、Explicit或sequential

ThreadStatic        Field(静态)         实现线程局部存储(TLS)。不能跨多个线程共享给定的静态字段,每个线程拥有这个静态字段的副本

ComVisibleAttribute  程序集、接口、类、结构、委托、枚举、字段、方法或属性

控制程序集中个别托管类型、成员或所有类型对 COM 的可访问性,默认为 true,指示该托管类型对 COM 是可见的。使所有公共托管程序集及类型可见并不需要使用此属性;默认情况下,它们对 COM 是可见的。只能使 public 类型可见。而不能使用该属性使原本为 internalprotected 的类型对 COM 可见,也不能使不可见类型的成员可见。

   在程序集上将该属性设置为 false 将隐藏该程序集中的所有 public 类型。通过将个别类型设置为 true,可以有选择地使程序集中的类型可见。如果对于某个特定类型将该属性设置为 false,则将隐藏该类型及其成员。但如果某个类型是不可见的,则无法使该类型的成员可见。如果对于某个类型将该属性设置为 false,则可防止该类型被导出到类型库;不注册类;接口从不响应非托管 QueryInterface 调用。
[ComVisibleAttribute(true)] 
DefaultMemberAttribute   public DefaultMemberAttribute (String memberName)

memberName 包含要调用的成员名称的 String。这可能是一个构造函数、方法、属性或字段。在调用成员时必须指定合适的调用属性。通过传递一个空 String 作为成员名称,可以指定类的默认成员。

能够通过InvokeMember调用默认成员,而不需要传递调用成员的名称。当需要绑定器但不需要特别的绑定行为时就可以使用它。

 

下面介绍几种常用的属性

1.[STAThread]和[MTAThread]属性

class Class1{

//使用STAThread属性将程序的默认线程模型指定为单线程模型。注意,线程模型只影响使用COM interop的应用程序,//将这个属性应用于不使用COM interop的程序将不会产生任何效果。

[STAThread]

Static void Main( string[] args ){

}

}

2. AttributeUsage属性

3.Conditional 属性:

这个属性附着于方法,这样当编译器遇到对这个方法调用时,如果没有定义对应的字符串值,编译器就忽略这个调用。例如,以下方法是否被编译取决于是否定义了字符串“DEGUG”:

#define DEBUG

#undef DEBUG
[Condition(“DEBUG”) ]
public void SomeDebugFunc() {
       Console.WriteLine(“SomeDebugFunc”);
}

4. Obsolete 属性 [Obsolete("Don't use OldFunc, use NewFunc instead", true)] 标记一个语言元素被废止

5. DllImport和StructLayout属性

DllImport可以让C#代码调用本机代码中的函数,C#代码通过平台调用(platform invoke)这个运行时功能调用它们。
 StructLayout:公共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管 内存中的物理布局,即类或结构需要按某种方式排列。如果要将类传递给需要指定布局的非托管代码,则显式控制类布局是重要的。它的构造函数中用 LayoutKind值初始化 StructLayoutAttribute 类的新实例。 LayoutKind.Sequential 用于强制将成员按其出现的顺序进行顺序布局。
 LayoutKind.Sequential 顺序布局  出现的每一个字段,在内存里按出现顺序依次排列

LayoutKind. Explicit   精确布局  需要用FieldOffset()设置每个成员的位置,这样就可以实现类似c的公用体的功能

[StructLayout(LayoutKind.Explicit)]
struct S1
{
[FieldOffset(0)] //这样a和b在内存中地址相同
int a;
[FieldOffset(0)] //这样a和b在内存中地址相同
int b;
}

using System;
using System.Runtime.InteropServices; // for DllImport
namespace nativeDLL
{
public class Test
{
//[DllImport ("user32.dll")] // all the defaults are OK
[DllImport("user32", EntryPoint="MessageBoxA",SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true,CallingC.StdCall)]
public static extern int MessageBoxA (int h, string m, string c, int type);

[DllImport ("kernel32.dll")]
public static extern void GetLocalTime(SystemTime st);

[StructLayout(LayoutKind.Sequential)] //
public class SystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}

[STAThread]
public static void Main(string[] args)
{
MessageBoxA(0, "Hello World", "nativeDLL", 0);
SystemTime st = new SystemTime();
GetLocalTime(st);
string s = String.Format("date: {0}-{1}-{2}",st.wMonth, st.wDay, st.wYear);
string t = String.Format("time: {0}:{1}:{2}", st.wHour, st.wMinute, st.wSecond);
MessageBoxA(0, s + ", " + t, "Now", 0);
}
}
}

6. 配件属性
       当使用.NET产生任何类型的C#工程时,会自动的产生一个AssemblyInfo.cs源代码文件以及应用程序源代码文件。 AssemblyInfo.cs中含有配件中代码的信息。其中的一些信息纯粹是信息,而其它信息使运行时环境可以确保惟一的命名和版本号,以供重用你的配件的客户代码使用。

7. 上下文属性
       .NET柜架还提供了另一种属性:上下文属性。上下文属性提供了一种截取机制,可以在类的实例化和方法调用之前和之后进行处理。这种功能用于对象远程调用,它是从基于COM的系统所用的COM+组件服务和Microsoft Transaction Services(MTS)。

使用c#中预定义 Attribute

 

开发自定义Attributes

在C#中,我们的attribute类都派生于System.Attribute类 (A class that derives from the abstract class System.Attribute, whether directly or indirectly, is an attribute class. The declaration of an attribute class defines a new kind of attribute that can be placed on a declaration)

using System; 
public class HelpAttribute : Attribute 

    public HelpAttribute(String Descrition_in)   { 
        this.description = Description_in; 
    } 
    protected String description; 
    public String Description   { 
        get   {    return this.description;  }             
    }     
}

[Help("this is a do-nothing class")] 
public class AnyClass  { 
}

注意:按惯例我们是用”Attribute“作为attribute类名的后缀,然而,当我们当我们把attribute绑定到某语言元素时,是不包含“Attribute“后缀的。编译器首先在System.Attribute 的继承类中查找该attribute,如果没有找到,编译器会把“Attribute“追加到该attribute的名字后面,然后查找它。
在上面的例子中,我们在attribute类中添加了一个属性,在最后一节中,我们将在运行时查询该属性。

 

定义或控制自定义Attribute的用法

AttributeUsage 类是另一预定义类(attribute类本身用这个atrribute System.AttributeUsage来标记),它提供三个属性帮助我们控制我们自定义attribute的用法,

ValidOn (在哪些元素上有效),值为AttributeTargets的枚举,支持bitwise(按位计算)

//指示 HelpAttribute只能用于类上,否则编译错误
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class HelpAttribute : Attribute {
public HelpAttribute(String Description_in){
this.description = Description_in;
}
protected String description;
public String Description{ get{ return this.description;} }
}

AllowMultiple是否允许在同一语言元素上使用多次,默认为false ,下面将产生编译错误

[Help("this is a do-nothing class")]
[Help("it contains a do-nothing method")] //AnyClass.cs: Duplicate(复制) 'Help' attribute
public class AnyClass{
[Help("this is a do-nothing method")] //error
public void AnyMethod(){
}
}

Inherited:当我们在基类上使用我们的自定义Attribute时,基类的派生类是否也继承基类上的Attribute,默认false。

Ok!现在我们该讨论下最后那个属性了,”Inherited”, 指出当把该attribute放置于一个基类之上,是否派生类也继承了该attribute。如果绑定至某个attribute类的”Inherited”被设为true,那么该attribute就会被继承,然而如果绑定至某个attribute类的”Inherited”被设为false或者没有定义,那么该attribute就不会被继承。

让我们假设有如下的类关系。

[Help("BaseClass")]

public class Base{

}

public class Derive : Base{

}

我们有四种可能的绑定:

//派生类无法查到HelpAttribute,因为”Inherited”被设为了false。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false )]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false) ]

//虽然允许被继承,若派生类中也定义该属性将重写基类的属性,因为不能多次在同一语言元素上多次使用
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
//若派生类也定义了自己的Attribute,查询时将得到包含基类Attribute在内的两个Attribute的实例
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true) ]

可选参数 vs命名参数   源于Attribute构造函数的不同签名 

可选参数:使用该Attribute时必须提供值的参数,

命名参数:使用该Attribute可以不提供值,使用Attribute默认值的参数

参数类型: 一个attribute类的参数类型被限定在如下类型中
bool,   byte,   char,   double,   float,  int,   long,   short,   string,   System.Type,   object,  
An enum type, provided that it and any types in which it is nested are publicly accessible.

A one-dimensional array involving any of the types listed above  //一位数组

Attribute

Attribute 标识符 

可能的标识符:assembly  module  type  method  property  event  field  param  return 
假设我们想把HelpAttribute绑定至元素 assembly。

第一个问题:我们要把Help attribute 放在哪儿才能让编译器确定该attribute是绑定至整个assembly呢?

第二个问题:我们想把attribute绑定至一个方法的返回类型上,怎样才能让编译器确定我们是把attribute绑定至方法的返回类型上,而不是整个方法呢?

[assembly: Help("something")]    //该attribute被绑定至整个assembly

[module: Help("something ")]

[type: Help("something ")]

[method: Help("something ")]

[property: Help("something ")]

[field: Help("something ")]

[param: Help("something ")]

[return: Help("something ")]

在运行时查询Attribute  Attribute的信息绑定在类所属的Type类型中

private void DoSomething() {
string assemblyFileName = Process.GetCurrentProcess().ProcessName + ".exe";
Assembly assembly = Assembly.LoadFrom(assemblyFileName);

HelpAttribute helpAttribute;
foreach (Attribute attribute in assembly.GetCustomAttributes(true))
{
helpAttribute = attribute as HelpAttribute;
if (helpAttribute != null){
string description = helpAttribute.Description;
}
}
}

1.     查询类、方法、类成员的Attribute 

首先应获得与相应与成员相关的类型(Type)对象,成员的Attribute信息都绑定在Type对象中 

private void GetAttributeInfo()
{
HelpAttribute helpAttribute;
Type classType = this.GetType();

//类的Attribute信息
foreach (Attribute attribute in classType.GetCustomAttributes(true))
{
if (attribute != null && (attribute is HelpAttribute))
{
helpAttribute = attribute as HelpAttribute;
string description = helpAttribute.Description;
}
}

//类的方法的Attribute信息
foreach (MethodInfo methodInfo in classType.GetMethods())
{
//methodInfo.Invoke("Object obj:对其调用方法或构造函数的对象,如果方法是静态的,则为null"
, "object[] parameters");
foreach (Attribute attribute in methodInfo.GetCustomAttributes(true))
{
if (attribute != null && (attribute is HelpAttribute))
{
helpAttribute = attribute as HelpAttribute;
string description = helpAttribute.Description;
}
}
}

//类的public的Field的Attribute信息
foreach (FieldInfo fieldInfo in classType.GetFields())
{
foreach (Attribute attribute in fieldInfo.GetCustomAttributes(true))
{
if (attribute != null && (attribute is HelpAttribute))
{
helpAttribute = attribute as HelpAttribute;
string description = helpAttribute.Description;
}
}
}
}

public class AnyClass
{
//标记了一个不该再被使用的语言元素:此为方法,同时把依然使用此方法的元素标记为错误,编译器产生警告
[Obsolete("Don’t use Old method, use New method", true)]
static void Old( ) { }
static void New( ) { }
public static void Main( )
{
Old( );
}
}

转载于:https://www.cnblogs.com/niumeng/archive/2010/12/03/1895368.html

Attribute in C#相关推荐

  1. Python错误:AttributeError: 'generator' object has no attribute 'next'解决办法

    今天在学习生成器对象(generation object)运行以下代码时,遇到了一个错误: #定义生成器函数 def liebiao(): for x in range(10): yield x #函 ...

  2. Error:warning: Ignoring InnerClasses attribute for an anonymous inner class

    最近安装项目到自己oppo手机上提示Error:warning: Ignoring InnerClasses attribute for an anonymous inner class,但是在模拟机 ...

  3. error: Error: No resource found for attribute ‘layout_scrollFlags’ in package‘包名’

    遇到error: Error: No resource found for attribute 'layout_scrollFlags' in package'包名' 这个问题时候刚开始自己也是感觉到 ...

  4. AttributeError: 'dict' object has no attribute 'status_code'

    前端AJAX请求数据,提示错误:"AttributeError: 'dict' object has no attribute 'status_code'". 原因:是提示返回对象 ...

  5. C# Attribute简介

    一 .EventAttribute有: BrowsableAttribute .CategoryAttribute.DescriptionAttribute.DefaultEventAttribute ...

  6. C# 特性(Attribute)学习。

    特性(attribute)是被指定给某一声明的一则附加的声明性信息. 在C#中,有一个小的预定义特性集合.在学习如何建立我们自己的定制特性(custom attributes)之前,我们先来看看在我们 ...

  7. Attribute在.net编程中的应用

    作者:niwalker       出处:csdn SqlCommandGenerator类的设计 SqlCommandGEnerator类的设计思路就是通过反射得到方法的参数,使用被SqlComma ...

  8. Attribute 绑定、类绑定和样式绑定

    Attribute 绑定.类绑定和样式绑定 1. 绑定到 Attribute 优先设置带有 Property 绑定的元素的 Property.如果没有可绑定的元素 Property,可以使用 Attr ...

  9. AttributeError: Cant get attribute SPPF on module models

    运行YOLOV5出现报错AttributeError: Can't get attribute 'SPPF' 问题 AttributeError: Can't get attribute 'SPPF' ...

  10. C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)

    反射以及Attribute在ORM中的应用 一. 反射 什么是反射? 简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等. 反射有什么用呢? 反射不但让 ...

最新文章

  1. 付睿:对新事物的追寻之旅 | 优秀毕业生专访
  2. MySQL_解决ERROR 2006 (HY000) at line XX MySQL server has gone away问题
  3. 睡觉觉睡觉睡觉计算机手机,孩子爱睡觉怎么回事
  4. Hadoop集群中添加硬盘
  5. notes belonging to given user
  6. 十一、CSS初始化详解
  7. 常用的比较排序算法总结
  8. 计算机网络(第七版)谢希仁编著 第四章课后答案详解
  9. AxureRP9授权码
  10. C++报错 invalid operands to binary expression
  11. 百度地图API之根据经纬度查询地址信息(Android) .(10)
  12. 用python实现矩形图片转换正方形(防失真 + 文件批量可操作)
  13. mysql 3306无法访问_Mysql 3306端口无法被远程机器访问
  14. 50G-PON,继10G PON之后的新一代PON技术
  15. C语言程序设计编辑与调试环境初级(已更完)
  16. 【修真院pm小课堂】登录注册的触发场景
  17. java自动违例设计,java违例
  18. 洛谷P4053 建筑抢修
  19. Python脚本翻译英文到汉语
  20. fitnesse 新手入门

热门文章

  1. 使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储)...
  2. extract($_POST[])
  3. 欢迎转载中国网站排名
  4. java B2B2C Springcloud仿淘宝电子商城系统
  5. 史蒂芬.霍金:警惕政府“人工智能军备竞赛”
  6. 使用webpack.require优化vue项目的路由
  7. 掌握面试——弹出框的实现
  8. SAS接口互连完全指南
  9. ueditor上传大容量视频报http请求错误的解决方法
  10. .NET领域驱动设计—初尝(原则、工具、过程、框架)