勇哥注:
C#的特性(attribute)常见于一些框架(例如wcf),控件(例如PropertyGrid),编译器控制等。
特性非常常见,它的本质是为对象提供额外的信息和行为,使用者可以通过反射读到这些信息或者使用这些行为。
特性是C#语言现代编程风格的重要特点。
特性常见的有两个方面的应用:
(一)可以修饰枚举。
这种应用相当于为对象添加了额外的信息。
例如下面的枚举,通过反射可以读出枚举项的额外信息。
[Remark("用户状态")] public enum UserState { /// <summary> /// 正常 /// </summary> [Remark("正常")] Normal = 0, /// <summary> /// 冻结 /// </summary> [Remark("冻结")] Frozen = 1, /// <summary> /// 删除 /// </summary> [Remark("删除")] Deleted = 2 }
上面的特性,实际上是我们自定义的一个类,它必须继承自Attribute类。
如下图代码中,我们定义的自定义特性叫RemarkAttribute。
而在前面枚举的时候,你只需要使用名字Remark就可以了,当然你要愿意的话,也可以使用RemarkAttribute。
下面代码中使用的了扩展方法,因此你可以对使用枚举使用方法GetRemark取得这个枚举项目的特性内容。
/// <summary> /// 是给枚举用 提供一个额外信息 /// </summary> [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] public class RemarkAttribute : Attribute { public RemarkAttribute(string remark) { this.Remark = remark; } public string Remark { get; private set; } } public static class RemarkExtend { /// <summary> /// 扩展方法 /// </summary> /// <param name="enumValue"></param> /// <returns></returns> public static string GetRemark(this Enum enumValue) { Type type = enumValue.GetType(); FieldInfo field = type.GetField(enumValue.ToString()); if (field.IsDefined(typeof(RemarkAttribute), true)) { RemarkAttribute remarkAttribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute)); return remarkAttribute.Remark; } else { return enumValue.ToString(); } } }
(二)可以为属性或者字段提供范围检查
这种相当于为对象添加了额外的行为操作。
例如下面是为字段添加的带有检查数据范围行为的特性:
[Custom(123, Description = "1234", Remark = "2345")]//方法不行 public class Student { [CustomAttribute] public int Id { get; set; } [Leng(5,10)]//还有各种检查 public string Name { get; set; } [Leng(20, 50)] public string Accont { get; set; } /// <summary> /// 10001~999999999999 /// </summary> [Long(10001, 999999999999)] public long QQ { get; set; } }
上面的特性Leng,来源于下面的自定义特性类
public abstract class AbstractValidateAttribute : Attribute { public abstract bool Validate(object value); } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class LengAttribute : AbstractValidateAttribute { private int _Min = 0; private int _Max = 0; public LengAttribute(int min, int max) { this._Min = min; this._Max = max; } public override bool Validate(object value)//" " { if (value != null && !string.IsNullOrWhiteSpace(value.ToString())) { int length = value.ToString().Length; if (length > this._Min && length < this._Max) { return true; } } return false; } }
(三)特性的总结
1。特性attribute,和注释的区别是:注释你无法通过反射取得,但是特性可以。
一个特性,如果没有使用者,它将无任何作用。
特性的使用者,可以是一个类,或者是一个框架,或者是编译器,或者是VistualStudio。
例如下面的特性:
[Obsolete("请不要使用这个了,请使用什么来代替", true)] //这个影响编译器的运行
[Serializable] //可以序列化和反序列化 可以影响程序的运行
其它的常见的特性有: wcf, MVC filter等。
2。 声明和使用attribute,AttributeUsage
特性可以修饰类、类的方法、类的属性、类的字段、枚举或枚举项。
被特性修饰后的对象,在C#的中间语言IL中,会插入一些类,以存储额外的信息或者行为。
只有通过ILSpy这类反编译工具才能看到这些变化。而在C#代码层面上,表面上特性就跟加一个注释没有什么区别。
3。特性的意义是运行中获取attribute:额外信息、 额外操作
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

