C#中的Attribute

dotNet框架中的内置Attribute

AttributeUsage

AttributeUsage是用于自定义新的特性类的标签,从这一自定义的流程,可以看出所谓的Attribute实质上是一个特殊的对象,用于对其他类的修饰与标注。

Conditional

Conditional特性主要用于标注编译器的预处理条件,相较于传统的#if DEBUG 等预处理指令,使用Conditional特性的[Conditional("DEBUG")]更能够适应对性能要求较高的项目开发。这是因为运行时在读取预处理指令时,JIT编译器会将符合或不符合预处理条件的指令都进行调用,不能被编译成IL。而使用Conditional特性的则能被JIT编译器识别,生成性能更高的IL。

Obsolete

Obsolete是一个用于提供编译时警告的标签,其用途主要是标记某个不该被使用的模块,比如旧的函数与类。在编译时,如果代码中有部分被标注了Obsolete,则编译器会抛出一条警告,警告内容为Obsolete标签中定义的值。

从装饰器到Attribute

作为一个学过多种程序设计语言的开发者,上手C#中Attribute相关文档的时候第一时间就想到了Python中的装饰器。

在Python中,装饰器主要用于修饰函数或类,事实上Python中的装饰器就是一个函数,其本质上是一个套在原函数外层的特殊函数,使得原函数成为一个闭包,从而实现某些高级功能。

而对C#来说,这个设计之初就以面向对象作为开发纲领的语言,其并没有Python那样浓郁的函数式编程的味道,粗看Attribute似乎只是作为一种特殊的标记与注释(aka. meta data),只不过其是写给编译器看的罢了。然而在经过一些更为深入的了解后,我意识到,通过反射,C#与Attribute能做到更多。

反射与Attribute

通过反射的方式,可以在程序运行过程中,访问对象的特性,从而确定对象元数据中的指定类型。

对于这一点,我目前想到了有以下应用思路:

  • 在构建数据库中间层ORM时,可以通过给定不同对象以不同的特性,通过反射来处理这些特性,可以加快相应模块的编码速度。
  • 可以将对象中一些较少被使用,或者与最终成品无关的信息通过Attribute存储起来,而且不同于属性,特性是可以选择无法被子类继承的

总结

C#作为一种强类型的静态语言,通过Attribute以及结合其他语法糖的高级用法,一定程度上能实现一些动态化的编程方法。这种方法无疑是对于程序设计与编码思路的一种开阔,随着C#的迭代,新特性不断被引入其中,dotNet框架中函数式编程的味道也越来越浓。在吸取了来自F#的经验后,C#的设计者也许会让这门语言的开发变得更加高效以及有趣