using AttributeStudy.ValidateExtend;
using System;
namespace AttributeStudy
{
class Program
{
static void Main(string[] args)
{
#region 特性的定义,创建
{
//[Serializable] //可以序列化和反序列化
//[Obsolete("过时的特性请不要使用")] //编译时提示,影响编译器
//[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] //影响编译器,AllowMultiple属性允许重复特性
//特性就是一个类,直接或间接继承Attribute
//自己定义的特性如果已Attribute结尾可以省略这个单词
//特性修饰可以修饰入参和返回值
//Student student = new Student
//{
// Id = 1,
// Name = "小王"
//};
//student.ManageStudent();
}
#endregion
#region 特性的应用一:给字段属性增加额外信息
//Console.WriteLine(UserState.Delete.GetRemark());
#endregion
#region 特性的应用二:属性规则验证
StudentVip stvip = new StudentVip
{
QQ = 100000,
Salary = 5100000,
Mobile = 27602904864,
Email = "240868339@qq.com"
};
stvip.Validate();
#endregion
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace AttributeStudy
{
[Serializable]
//[Obsolete("过时的特性请不要使用")] //编译时提示,影响编译器
[My()]
[My(2)]
[My("", Remark = "123", Discription = "ppp")]
[MyAttributeChild]
public class Student
{
public int Id { set; get; }
[My,My(1)]
public string Name { set; get; }
[return: My, My(2, Remark = "", Discription = ""), MyAttributeChild]//特性修饰返回值
public string Answer([My]string name)//特性修饰入参
{
return $"my name is {name}";
}
}
}
student的扩展方法
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace AttributeStudy
{
public static class InvokeCenter
{
public static void ManageStudent<T>(this T t) where T : Student
{
Type type = t.GetType();
if (type.IsDefined(typeof(MyAttribute), true))
{
object[] oAttributeArr = type.GetCustomAttributes(typeof(MyAttribute), true);
foreach (MyAttribute attribute in oAttributeArr)//将object强转成MyAttribute
{
attribute.show();
}
foreach (PropertyInfo prop in type.GetProperties())
{
if (type.IsDefined(typeof(MyAttribute), true))
{
object[] oPropAttributeArr = prop.GetCustomAttributes(typeof(MyAttribute), true);
foreach (MyAttribute attribute in oPropAttributeArr)//将object强转成MyAttribute
{
attribute.show();
}
}
}
foreach (MethodInfo method in type.GetMethods())
{
if (type.IsDefined(typeof(MyAttribute), true))
{
object[] oMethodAttributeArr = method.GetCustomAttributes(typeof(MyAttribute), true);
foreach (MyAttribute attribute in oMethodAttributeArr)//将object强转成MyAttribute
{
attribute.show();
}
}
}
}
}
}
}
给枚举增加信息
using System;
using System.Collections.Generic;
using System.Text;
namespace AttributeStudy
{
public enum UserState
{
/// <summary>
/// 正常
/// </summary>
[Remark("正常")]
Normal = 0,
/// <summary>
/// 已冻结
/// </summary>
[Remark("已冻结")]
Frozen = 1,
/// <summary>
/// 已删除
/// </summary>
[Remark("已删除")]
Delete = 2,
}
}
枚举的扩展方法
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace AttributeStudy
{
public static class AttributeExtend
{
public static string GetRemark(this Enum @enum)
{
Type type = @enum.GetType();
FieldInfo field = type.GetField(@enum.ToString());
if (field.IsDefined(typeof(RemarkAttribute), true))
{
RemarkAttribute attritube = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute), true);
return attritube.Remark;
}
else
{
return @enum.ToString();
}
}
}
}
利用特性验证
using AttributeStudy.ValidateExtend;
using System;
using System.Collections.Generic;
using System.Text;
namespace AttributeStudy
{
public class StudentVip
{
public string Name { set; get; }
[LongAttribute(10_000, 9_999_999)]
public long QQ { set; get; }
[NotNull]
[LongAttribute(500_000, 1_000_000)]
public int Salary { set; get; }
[Mobile]
public long Mobile { set; get; }
[Email(@"^\w+@\w+.\w+$")]
public string Email { set; get; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace AttributeStudy
{
public abstract class AttributeBaseModel : Attribute
{
public abstract bool isValidable(object value);
}
}
扩展方法
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace AttributeStudy.ValidateExtend
{
public static class AttributeExtend
{
public static bool Validate<T>(this T t)
{
List<string> Err = new List<string>();
Type type = t.GetType();
foreach (PropertyInfo prop in type.GetProperties())
{
if (prop.IsDefined(typeof(AttributeBaseModel), true))
{
object[] attributeArr = prop.GetCustomAttributes(typeof(AttributeBaseModel), true);
foreach (AttributeBaseModel attribute in attributeArr)
{
if (!attribute.isValidable(prop.GetValue(t)))
{
Err.Add($"{prop.Name}'s value is {prop.GetValue(t)} no validable");
//Console.WriteLine($"{prop.Name}'s value is {prop.GetValue(t)} no validable");
//return false;
}
}
}
}
if (Err.Count > 0)
{
foreach (var str in Err)
{
Console.WriteLine(str);
}
}
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace AttributeStudy.ValidateExtend
{
[AttributeUsage(AttributeTargets.Property)]
public class EmailAttribute : MobileAttribute
{
public new string Pattern { private set; get; }
public EmailAttribute()
{
Pattern = @"^\w+@\w+.\w+$";
}
public EmailAttribute(string pattern)
{
Pattern = pattern;
}
public override bool isValidable(object obj)
{
if (obj == null)
return false;
return Regex.IsMatch(obj.ToString(), Pattern);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace AttributeStudy.ValidateExtend
{
[AttributeUsage(AttributeTargets.Property)]
public class LongAttribute : AttributeBaseModel
{
private long _min = 0;
private long _max = 0;
public LongAttribute(long min, long max)
{
_min = min;
_max = max;
}
public override bool isValidable(object value)
{
return value != null
&& long.TryParse(value.ToString(), out long number)
&& number >= _min && number <= _max;
}
}
}