通过特性提供额外行为的实例:自定义特性做数据验证(效验属性值的大小和非空)
学生类中有个QQ的属性,效验QQ不能小于100000(5位数),不能大于999999999999(12位数),并且QQ的属性不能为空。如果满足这些效验返回true,否则返回false。
声明一个抽象类,所有的自定义特性都继承自这个抽象类,为了确保自定义特性都实现数据效验的方法。
/// <summary>
/// 抽象类 基类
/// </summary>
public abstract class AbstractVaildDataAttribute : Attribute
{
/// <summary>
/// 验证数据是否符合要求
/// </summary>
/// <param name="oValue"></param>
/// <returns></returns>
public abstract bool ValidData(object oValue);
}
声明效验属性非空的特性:
/// <summary>
/// 声明一个可以对属性应用 空字符串效验的特性
/// 效验值是否为空
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class RequireAttribute : AbstractVaildDataAttribute
{
public override bool ValidData(object oValue)
{
return !string.IsNullOrEmpty(oValue.ToString());
}
}
声明效验属性值大小的特性:
/// <summary>
/// 声明一个可以对属性应用LongAttribute的特性
/// 效验值的范围
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class LongAttribute : AbstractVaildDataAttribute
{
private long _Min = 0;
private long _Max = 0;
public LongAttribute(long min, long max)
{
_Min = min;
_Max = max;
}
public override bool ValidData(object oValue)
{
long lValue = 0;
return oValue != null && long.TryParse(oValue.ToString(), out lValue) && lValue >= _Min && lValue <= _Max;
}
}
声明一个学生类,并在属性上面添加上自定义的两个特性(‘Long’,‘Require’):
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
[Long(10000, 999999999999)]
[Require]
public long QQ { get; set; }
}
声明一个扩展方法,用于调用反射来效验属性的值:
/// <summary>
/// 效验属性的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public static bool ValidDataExtend<T>(this T t) {
Type type = t.GetType();
foreach (var prop in type.GetProperties())
{
if (prop.IsDefined(typeof(AbstractVaildDataAttribute),true))
{
object oValue = prop.GetValue(t);//获取要校验类型的值
object[] oAttributeArr = prop.GetCustomAttributes(typeof(AbstractVaildDataAttribute), true);//获取所有自定义的特性
foreach (AbstractVaildDataAttribute attr in oAttributeArr)
{
if (!attr.ValidData(oValue))
{
return false;
}
}
}
}
return true;
}
调用扩展方法,验证特性效果:
static void Main(string[] args)
{
Student student = new Student()
{
Id = 1,
Name = "张三",
QQ = 1234565555
};
if (student.ValidDataExtend())
{
Console.WriteLine("效验通过");
}
else
{
Console.WriteLine("效验不通过");
}
Console.ReadKey();
}
执行结果:
整体实现思路:
1.声明抽象类(基类)
2.声明非空效验特性和数值大小效验特性
3.在属性上面应用特性
4.使用反射访问特性,效验数值是否符合要求