温故而知新:c#中的特性(attribute)
特性(Attribute)是微软在.Net中自创的一种新技术,对于很多初学者来讲,特性一直是一块难啃的骨头。
既然弄不懂,那我们就暂时绕过它吧,回想一下我们在写代码时通常都要求写注释,为了是让别人或自己以后能看得懂,但是这个注释是写给“人”看的,突发奇想一下:我们能不能写出一种注释,给c#编译器看,比如我们在某些代码上打个标记,让编译器看到这些标记后,做出不同的反应?
其实...这就是特性,比如我们定义一个常规的类
public class Product
{
public string Name { set; get; }
public decimal Price { set; get; }
}
常规这样编译时,Product并不支持序列化,但只要我们在前面加上一行代码,比如:
[Serializable]
public class Product
{
public string Name { set; get; }
public decimal Price { set; get; }
}
编译器在编译时就能做出反应:哦,原来Product要求支持序列化,我晓得了 :)
这里的[Serializable]就是一个特性,一个类被应用该特性后,编译器编译时会查找SerializableAttribute这个类(即:自动添加Attribute后缀),并检测该类是否继承自Attribute,如果找到则会调用SerializableAttribute的默认构造器生成一个该类的实例,然后会生成相应的信息一起附加到Product类的元数据里,然后这些附加的特性元数据,可以通过反射调用。
下面这些代码摘自Anytao的大作"您必须知道的.Net"一书:
public class MyselfAttribute : System.Attribute
{
private string _name;
private int _age;
private string _memo;
public MyselfAttribute() { }
public MyselfAttribute(string name, int age)
{
_name = name;
_age = age;
}
public string Name
{
get { return _name == null ? string.Empty : _name; }
}
public int Age { get { return _age; } }
public string Memo
{
set { _memo = value; }
get { return _memo; }
}
public void ShowName()
{
Console.WriteLine("Hello,{0}", _name == null ? "word." : _name);
}
}
上面定义了一个特性类,单独看它跟普通类没有任何区别,下面看一下如何应用:
[Myself("Emma", 25, Memo = "my good girl.")]
public class Mytest
{
public void SayHello()
{
Console.WriteLine("Hello,my.net world.");
}
}
这里将刚才的MyselfAttribute特性应用到Mytest类上面了,注意写法:后缀Attribute可以省略
[Myself("Emma", 25, Memo = "my good girl.")]
这一行的含义相当于
new MyselfAttribute("Emma",25){Memo = "my good girl."}
最后看一下如何应用:
using System;
using System.Reflection;
...
static void Main(string[] args)
{
Type info = typeof(Mytest);
MyselfAttribute myattribute = (MyselfAttribute)Attribute.GetCustomAttribute(info, typeof(MyselfAttribute));
if (myattribute != null)
{
Console.WriteLine("Name:{0}", myattribute.Name);
Console.WriteLine("Age:{0}", myattribute.Age);
Console.WriteLine("Memo of {0} is {1}", myattribute.Name, myattribute.Memo);
myattribute.ShowName();
}
//多点反射
object obj = Activator.CreateInstance(typeof(Mytest));
MethodInfo mi = info.GetMethod("SayHello");
mi.Invoke(obj, null);
Console.ReadLine();
}
运行结果:
Name:Emma
Age:25
Memo of Emma is my good girl.
Hello,Emma
Hello,my.net world.
这里解释一下:假如Mytest没有应用MyselfAttribute的话,MyselfAttribute myattribute = (MyselfAttribute)Attribute.GetCustomAttribute(info, typeof(MyselfAttribute)) 肯定会返回null,而正是因为应用了特性之后,才能得到这些附加的特性信息,从而在if包含的代码块中利用反射调用成功。
最后要指出的是:attribute在使用中,还能指定应用的目标对象(比如我们可以只让某特性应用于某一个Method或Field,默认情况下特性可应用于所有类型的目标),除此之外,还能指定该特性是否能应用多次...详情请参阅MSDN上的Attribute类
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- pytorch和tensorflow的爱恨情仇之参数初始化
- scp命令
- osgEarth使用笔记4——加载矢量数据
- Pots(POJ - 3414)【BFS 寻找最短路+路径输出】
- Vue路由Hash模式分析
- Flutter基础widgets教程-CupertinoButton篇
- 利用TfidfVectorizer进行中文文本分类(数据集是复旦中文语料)
- 组合模式
- Js中数组空位问题
- 反转字符串
- Prime Path(POJ - 3126)【BFS+筛素数】
- (leetcode每日打卡)秋叶收藏集【动态规划】
- 设计模式~调停者模式(Mediator)
- Sequential Nim(CodeForces - 1382B)【博弈】
- Less Coin Tosses(Gym - 102346L)【打表+找规律】