通過特性提供額外行為的執行個體:自定義特性做資料驗證(效驗屬性值的大小和非空)
學生類中有個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();
}
執行結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyMTOyIDOwkTM4ETMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
整體實作思路:
1.聲明抽象類(基類)
2.聲明非空效驗特性和數值大小效驗特性
3.在屬性上面應用特性
4.使用反射通路特性,效驗數值是否符合要求