勇哥注:
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
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路


















