C#之自定义特性

  在前面介绍的代码中有使用特性,这些特性都是Microsoft定义好的,作为.NET Framework类库的一部分,许多特性都得到了C#编译器的支持。
  .NET Frmework也允许定义自己的特性。自定义特性允许把自定义元数据与程序元素关联起来。这些元数据是在编译过程中创建的,并嵌入到程序集中。这些特性不会影响编译过程,因为编译器不能识别它们,但这些特性在应用于程序元素时,可以在编译好的程序集中用作元数据。这些元数据在文档说明中很有用。使自定义特性起很大作用的是反射(http://www.cnblogs.com/afei-24/p/6867986.html)技术,代码可以读取这些元数据,使用它们在运行期间作决策。

一.编写自定义特性

    [FieldName("Social")]
        public string SocialNumber
        {
            ...
        }

  当C#编译器发现SocialNumber属性应用了一个FieldName特性时,首先会把字符串Attribute追加到FieldName这个名称后面,形成一个组合名称FieldNameAttribute,然后在其搜索路径的所有名称空间(即在using语句中提及的名称空间)中搜索FieldNameAttribute类。但如果该特性的名称以字符串Attribute结尾,编译器就不会把这个字符串加到组合名称中。
  因此上面的代码等价于:

    [FieldNameAttribute("Social")]
        public string SocialNumber
        {
            ...
        }

  1.AttributeUsage特性
  自定义的特性类需要直接或间接派生自System.Attribute。这个类还应包含控制用法的信息:
    *特性可以应用到哪些类型的程序元素上(类,结构,属性和方法等)
    *特性是否可以多次应用到同一个程序元素上
    *特性在应用到类或接口上时,是否由派生类和接口继承
    *这个特性有哪些必选和可选参数
  如果编译器找不到对应的特性类,或者找到一个这样的特性类,但使用特性的方式与特性类中的信息不匹配,编译器就会产生一个编译错误。

  定义FieldNameAttribute特性

    [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]
        public class FieldNameAttribute:Attribute
        {
            private string name;
            public FieldNameAttribute(string name)
            {
                this.name = name;
            }
        }

  特性类FieldNameAttribute本身用了一个特性System.AttributeUsage来标记。这是Microsoft定义的一个特性,C#编译器为它提供了特殊的支持。AttributeUsage主要用于标识自定义特性可以应用到哪些类型的程序元素上。这些信息由它的第一个参数AttributeTargets给出,该参数是必选的,其类型是枚举类型AttributeTargets。上面的例子,指定FieldNameAttribute特性只能应用到属性上。
  AttributeTargets枚举的成员如下:
  
  上面列出了可以应用该特性的所有程序元素。在把特性应用到程序元素上时,应把特性放在元素前面的方括号中:
  [FieldName("Social")]
  public string SocialNumber
  {
    ...
  }
  但在应用到Assembly和Module时,特性可以应用到整个程序集或模块中,而不是应用到代码中的一个元素上,在这种情况下,这个特性可以放在源代码的任何地方,但需要使用关键字Assembly和Module作为前缀:
  [assembly:FieldName("Social")]
  [module:FieldName("Social")]

  在指定自定义特性的有效目标元素时,可以使用OR运算符(|)把这些值组合起来:
  [AttributeUsage(AttributeTargets.Property |AttributeTargets.Field,
    AllowMultiple=false, Inherited=false)]
  public class FieldNameAttribute:Attribute
  {
    private string name;
    public FieldNameAttribute(string name)
    {
      this.name = name;
    }
  }
  也可以使用AttributeTargets.All指定自定义特性可以应用到所有类型的程序元素上。

  AttributeUsage特性还包含另外两个参数:AllowMultiple和Inherited。它们用不同的语法来指定:参数名 = 参数值,而不是只给出这些参数的值。这些参数是可选的。
  AllowMultiple参数表示一个特性是否可以多次应用到同一项上。
  Inherited参数表示应用到类或接口上的特性是否自动应用到所以派生的类或接口上。如果特性应用到方法或属性上,它就自动应用到它们的重写版本上。

  2.指定特性参数
  [FieldName("Social")]
  public string SocialNumber
  {
    ...
  }
  编译器会检查传递给特性的参数(在本例中,是一个字符串),并产兆该特性类中带这些参数的构造函数。如果找到匹配的构造函数,编译器就会把指定的元数据传递给程序集。如果找不到,就会生成一个编译错误。反射()会从程序集中读取元数据,并实例化它们表示的特性类。因此,编译器需要确保存在这样的构造函数,才能在运行期间实例化指定的特性。

  3.特性的可选参数
  在AttributeUsage特性中,使用参数名 = 参数值语法把可选参数添加到特性中。这种语法指定可选参数的名称和值,它通过特性类中的公共属性或字段起作用:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]
        public class FieldNameAttribute:Attribute
        {
            private string name;
            public FieldNameAttribute(string name)
            {
                this.name = name;
            }

            public string Comment
            {
                get;set;
            }
        }

        [FieldName("Social",Comment="可选参数值")]
        public string SocialNumber
        {
            ...
        }
时间: 2024-10-09 23:47:49

C#之自定义特性的相关文章

自定义特性。配合枚举使用棒棒哒

1 /// <summary> 2 /// 自定义特性,比系统的display增加了一些参数 Created by ZhangQC 2015.08.19 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, 5 AllowMultiple = false, Inherited = false)] 6 public sealed class CustomAttrib

自定义特性用途---案例:操作权限

--------------------------------------------------LimitAttribute.cs   自定义特性 using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// LimitAttribute 的摘要说明 /// </summary> //特性只作用与方法上 [AttributeUsage(

C#编程(七十一)---------- 自定义特性

自定义特性 在说自定义之前,有必要先介绍一些基本的概念. 元数据:就是C#中封装的一些类,无法修改,类成员的特性被称为元数据中的注释 1.什么是特性? (1)属性和特性的区别 属性:属性是面向对象思想里所说的封装在类里面的数据字段,Get,Set方法. 特性:就相当于类的元数据. 来看看官方解释? 特性是给指定的某一声明的一则附加的声明性信息. 允许类似关键字的描述声明.它对程序中的元素进行标注,如类型.字段.方法.属性等.从.net角度看,特性是一种 类,这些类继承于System.Attrib

.Net之自定义特性

刚接触C#的朋友常常容易把属性(Property)跟特性(Attribute)搞混,其实这是两种不同的东西 属性指的类中封装的数据字段:而特性是对类.字段.方法和属性等元素标注的声明性信息 如下代码(Id.Name为User的属性,[DbKey]为Id的特性) /// <summary> /// 用户信息 /// </summary> public class User { [DbKey] public string Id { get; set; } public string N

.Net:自定义特性(Custom Attributes)的创建与查看

有时候,我们会看到这样的东西放在类或者方法上面: [Obsolete("请更新方法")] 刚开始的时候,还自己给它起了个名字--小标签,比如,平常会说:你数据契约是不是没打标签啊!~嘿嘿~ 后来跟代码发现了更多的不认识的自定义标签.那么,这些标签是怎么定义和使用的呢? 定义Attribute 如下,定义了一个用于记录类变更的attribute,不允许继承,允许多次使用. [AttributeUsage(AttributeTargets.Class, Inherited = false,

Shader的自定义特性使用

使用自定义特性关键字,可以达到动态对Shader某一部分代码进行开关的操作 shader(定义了KEYWORD1特性): 定义:#pragma shader_feature KEYWORD1 判断:#ifdef KEYWORD1 Shader "Custom/NewSurfaceShader" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)",

C#自定义特性实例

元数据,就是C#中封装的一些类,无法修改.类成员的特性被称为元数据中的注释. 1.什么是特性   (1)属性与特性的区别  属性(Property):属性是面向对象思想里所说的封装在类里面的数据字段,Get,Set方法.  特性(Attribute):  官方解释:特性是给指定的某一声明的一则附加的声明性信息. 允许类似关键字的描述声明.它对程序中的元素进行标注,如类型.字段.方法.属性等.从.net角度看,特性是一种 类,这些类继承于System.Attribute类,用于对类.属性.方法.事

数据验证(自定义特性)

这几天在了解ef,看了几天云里雾里(我太菜了),但在vs2010中使用ef时我觉得有些东西还是很有意思的.自己便想到分装一个逻辑层的数据验证类 1.自定义特性 [AttributeUsage(AttributeTargets.Property)] public class CheckAttributes:Attribute { // 摘要: // 初始化类的新实例. public CheckAttributes(bool iskey, bool isnull) { this.EntityKeyP

Attribute(二)——自定义特性+Asp.net MVC中的filter详解

上篇博客是关于特性中有关预定义特性的一些基础,同时也是对Attribute这一概念的一个宏观上的认识,在上篇博客结尾介绍了有关为自定义特性服务的AttributeUsage,这篇博客主要是通过filter的使用间接的了解自定义特性的具体应用. 一.filter简介 在了解自定义特性前,先引入一个概念filter,它是MVC中自带的一种功能,在我们项目中通常会遇到在Action执行前或结束时,去执行日志记录或错误处理等功能,通常可使用AOP截取来实现,但是在MVC中提供了filter过滤,大大方便