• .NET 特性Attribute[一]


         C#允许开发人员以特性(attribute)形式为程序添加说明性的信息。特性可以定义与类,结构体,方法等相关的附加信息(元数据)。在.NET1.1时代。特性用的不是很多。但到了2.0,3.0特性应用就广泛起来了。因为今天在这里给还有一些不理解特性的朋友一起来学习一下!

    1.Attribute基础:

         特性(也有人称为属性)由System.Attribute的派生类来支持。因此所有的我类必须都是Attribute的子类。尽管Attribute类定义了大量的功能,但使用特性时一般不会用到全部功能。按照惯例,特性类名通常都使用Attribute作为后缀。例如ErrorAttribute是一个描述错误的特性类的名称。

         在声明特性类时,前面应该加上AttributeUsage特性。它是一个内置的特性,指明了我们声明的特性适用的元素的类型。例如,把特性限定为仅供方法使用。

    2.Attribute作为编译器的指令

         C#中已经内置了一些编译器的指令,如:#define DEBUG, #undefine DEBUG, #if等。这些指定是仅限于C#使用的,并且数量上是固定的。而Attribute作为编译器指定,在数量上是不固定的。比如以下三个内置的特性

         a.Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用。

         b.DllImport:用来标记非.NET的函数,表明该方法在一个外部的DLL中定义。

         c.Obsolete:这个属性用来标记当前的方法已经被废弃,不再使用了。

         以下代码演示Conditional使用

    #define DEBUG //这里定义条件

    using System;
    using System.Diagnostics;

    namespace AttributeDemo
    {
        
    /// <summary>
        
    /// Class1 的摘要说明。
        
    /// </summary>
        class Class1
        {
            
    /// <summary>
            
    /// 应用程序的主入口点。
            
    /// </summary>
            [STAThread]
            
    static void Main(string[] args)
            {
                ShowMsg();
                ShowMsg2();
                 
                Console.ReadLine();

            }

            [Conditional(
    "DEBUG")]
            
    private static void ShowMsg()
            {
                Console.WriteLine(
    "开始运行Main子程序。当前时间是"+DateTime.Now);
            }


            [Conditional(
    "DEBUG")]            
            
    private static void ShowMsg2()
            {
                Console.WriteLine(
    "开始运行Main子程序。当前时间是"+DateTime.Now.ToString("yyyy-MM-dd"));
            }

        }
    }

    可以看到 ,使用特性是非常简单。只需要将[Conditional]加在方法声明前即可。需要特别注意的是Attribute是在编译的时候被实例化的。而不是通用的在运行时实例化。

    上述程序运行时会输出二段话。而如果将代码第 一行定义debug注释起来,然后将编译模式改为Release版本(改为Release版本的原因是,如果在DEBUG模式下。条件DEBUG总为真)。则发现看不见任何结果。这就是特性的的一种运用。

    从2003迁到2005开发环境下的朋友会发现,当使用2003下的方式去读取web.config中的appSetting时,会给出一个提示警告,方法已过期!这看起来很有意思。那么我们自己是否可以实现类似友好功能,提示组件使用者,建议使用我们的新的方法代替旧有的呢?答案是肯定的,即使用Obsolete特性。如下

    [Conditional("DEBUG")]
            [Obsolete(
    "该方法已经过时,建议使用ShowMsg2()方法代替")]
            
    private static void ShowMsg()
            {
                Console.WriteLine(
    "开始运行Main子程序。当前时间是"+DateTime.Now);
            }


            [Conditional(
    "DEBUG")]            
            
    private static void ShowMsg2()
            {
                Console.WriteLine(
    "开始运行Main子程序。当前时间是"+DateTime.Now.ToString("yyyy-MM-dd"));
            }

    在ShowMsg方法上添加 不念旧恶Obsolete特性,并传入一段说明性的参数。则我们会发现

         

    编译器根据我们加入的特性给出了预期的提示。

    Attribute类

    除了.NET内置提供的一些特性外,我们当然也可以自定义自己的Attribute。需要知道的中,所有自定义的Attribute都必须派生自类Attribute。在开发自定义的Attribute的时候,还有一点需要注意的是特性可以施加到不同的元素中,如方法,属性,类,参数等。有时候我们可能希望自定义的特性只允许施加到类中,这时还可以使用AttributeUsage限定特性的使用范围。

    以下给出一个使用示例

    using System; 
    namespace AttTargsCS 


       
    // 该Attribute只对类有效. 
       [AttributeUsage(AttributeTargets.Class)]
       
    public class ClassTargetAttribute : Attribute 
       { 
        } 


       
    // 该Attribute只对方法有效. 
       [AttributeUsage(AttributeTargets.Method)]
       
    public class MethodTargetAttribute : Attribute 
       { 
        } 


       
    // 该Attribute只对构造器有效。
       [AttributeUsage(AttributeTargets.Constructor)]
       
    public class ConstructorTargetAttribute : Attribute 
       { 
        } 


       
    // 该Attribute只对字段有效. 
       [AttributeUsage(AttributeTargets.Field)]
       
    public class FieldTargetAttribute : Attribute
       {
       } 

       
      
    // 该Attribute对类或者方法有效(组合). 
      [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]
       
    public class ClassMethodTargetAttribute : Attribute
       {
        } 


       
    // 该Attribute对所有的元素有效.
       [AttributeUsage(AttributeTargets.All)]
       
    public class AllTargetsAttribute : Attribute 
      { 
       } 

       
    //上面定义的Attribute施加到程序元素上的用法
       [ClassTarget]  //施加到类
       [ClassMethodTarget]//施加到类
       [AllTargets] //施加到类
       public class TestClassAttribute
       { 
          [ConstructorTarget] 
    //施加到构造器
          [AllTargets] //施加到构造器
          TestClassAttribute()
          { 
           } 

          [MethodTarget] 
    //施加到方法
          [ClassMethodTarget] //施加到方法
          [AllTargets] //施加到方法
          public void Method1()
          {
          }
         
          [FieldTarget] 
    //施加到字段
          [AllTargets] //施加到字段
          public int myInt; 

          
    static void Main(string[] args)
          { 
          } 
       }

  • 相关阅读:
    CentOS7 下部署 Iptables 环境纪录(关闭默认的firewalle)
    Linux系统下root密码遗忘等系统故障的修复方法
    LDAP学习笔记总结
    kvm虚拟化关闭虚拟网卡virbr0的方法
    Gradle使用指南
    Android 注解工具 ButterKnife
    Sublime Text + CTags + Cscope (部分替代Source Insight)
    win + linux + android 多任务分屏
    Ubuntu16.04 安装openjdk-7-jdk
    eclipse + Android Studio 集成 Genymotion 模拟器
  • 原文地址:https://www.cnblogs.com/eflylab/p/1287155.html
Copyright © 2020-2023  润新知