C#特性Attribute
特性其实是一个类,是直接/间接继承自Attribute
约定俗成是以Attribut结尾,在标记的时候以[]包裹,尾部的Attribut可以省略掉;
通过反编译之后,在中间语言IL中我们发现标记特性的元素内部都生成了一个.Custom,但是我们调用不了;
自定义特性
/// <summary> /// 自定义特性 /// AllowMultiple =true:标记在特性上的特性,其实是对特性的一种约束; /// Inherited =true:约束当前特性是否可以继承 /// AttributeTargets.All:当前特性可以标记在所有的元素上 /// AttributeUsage:在定义特性的时候,对特性的一种约束,老师也建议大家自己以后在声明特性的时候,加上这个,就相当于明确告诉别人,我这个特性只能标记在哪些地方; /// </summary> [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] public class CustomAttribute : Attribute { public CustomAttribute() { } public CustomAttribute(int id) { } public CustomAttribute(string name) { } public CustomAttribute(int id,string name) { this.Id = id; this.Name = name; } public string Description; public int Id { get; set; } public string Name { get; set; } public int Do() { return 1; } } public class CustomAttributeChild : CustomAttribute { }
通过特性获取枚举描述
[AttributeUsage(AttributeTargets.Field)] public class RemarkAttribute : Attribute { public string Remark { get; private set; } public RemarkAttribute(string remark) { this.Remark = remark; } }
/// <summary> /// 在数据库中存在一个字段对应的就是这个枚举,数据库中存储的其实是数字,0,1,2 /// </summary> //[RemarkAttribute] public enum UserStuta { /// <summary> /// 正常状态 /// </summary> [RemarkAttribute("正常")] Normal = 0, /// <summary> /// 已冻结 /// </summary [RemarkAttribute("已冻结")] Frozen = 1, /// <summary> /// 已删除 /// </summary> [RemarkAttribute("已删除")] Deleted = 2 }
public static class RemarkExtension { public static string GetRemark(this Enum @enum) //扩展方法 { Type type = @enum.GetType(); FieldInfo? fileInfo = type.GetField(@enum.ToString()); if (fileInfo != null) { if (fileInfo.IsDefined(typeof(RemarkAttribute), true)) { RemarkAttribute remarkAttribute = (RemarkAttribute)fileInfo.GetCustomAttribute(typeof(RemarkAttribute), true); return remarkAttribute.Remark; } } return @enum.ToString(); } }
调用
var normal = UserStuta.Normal; string strnormal = RemarkExtension.GetRemark(normal); //获取枚举描述
通过特性校验数据
public static bool Validate<T>(T t) { Type type = t.GetType(); foreach (PropertyInfo prop in type.GetProperties()) { ///验证手机号长度 //if (prop.IsDefined(typeof(MobileNumAtrribute), true)) //{ // object oValue = prop.GetValue(t); // MobileNumAtrribute atrribute = prop.GetCustomAttribute<MobileNumAtrribute>(true); // if (!atrribute.Validate(oValue)) // { // return false; // } //} /////这就是验证QQ //if (prop.IsDefined(typeof(QQAttribute), true)) //{ // object oValue = prop.GetValue(t); // QQAttribute atrribute = prop.GetCustomAttribute<QQAttribute>(true); // if (!atrribute.Validate(oValue)) // { // return false; // } //} //如果后续还需要再加一个验证呢?那岂不是 又要修改代码? //这样做是坑,抽象~~ if (prop.IsDefined(typeof(AbstractValidateAttribute), true)) { object oValue = prop.GetValue(t); AbstractValidateAttribute atrribute = prop.GetCustomAttribute<AbstractValidateAttribute>(true); if (!atrribute.Validate(oValue)) { return false; } } } return true; }
public abstract class AbstractValidateAttribute : Attribute
{
public abstract bool Validate(object value);
}
bool bResult = Validate<StudentVip>(vip);

浙公网安备 33010602011771号