惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园_首页
GbyAI
GbyAI
罗磊的独立博客
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
U
Unit 42
V
Visual Studio Blog
F
Fortinet All Blogs
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
T
Tor Project blog
Martin Fowler
Martin Fowler
K
Kaspersky official blog
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
D
DataBreaches.Net
博客园 - Franky
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
P
Proofpoint News Feed
N
Netflix TechBlog - Medium
美团技术团队
S
Secure Thoughts
C
Cisco Blogs
M
MIT News - Artificial intelligence
L
Lohrmann on Cybersecurity
T
Tenable Blog
N
News and Events Feed by Topic
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Check Point Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Spread Privacy
Spread Privacy
S
Security @ Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
A
Arctic Wolf
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
T
Threat Research - Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
O
OpenAI News
V
Vulnerabilities – Threatpost

博客园 - 冯岩

RSA算法 Android JAVA C#互通 jquery.autocomplete.js 插件的自定义搜索规则 LINQ TO SQL 动态查询 ASPX多服务器控件下使用Jquery.validate.js 接受来自服务器的数据连接时发生超时(30000 毫秒)问题原因及解决方法 防止网页被客户端IE缓存 dottext阅读之系统调度分析 Javascript对日期的操作 C#读取被进程占用的文件 SqlServer 无日志文件附加 windows2003远程桌面退出后系统自动注销的解决方法 JS获取触发事件元素的方法 JS处理选取值 Marquee首尾相连不间断移动 开始完全显示 c#将数据导入Excel另类方法 windows Server 2008常见问题及解决方法 .NET 特性Attribute[三] .NET 特性Attribute[二] [安装程序配置服务器失败]解决SQL Server2000安装失败
.NET 特性Attribute[一]
冯岩 · 2008-09-08 · via 博客园 - 冯岩

     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)
      { 
      } 
   }