前言
c# 屬性類也稱做特性。這是一篇墊文,為后面的過濾器和其他特性類的東西做鋪墊。
正文
看一段代碼:
static void Main(string[] args)
{
Attribitefunc1.printMesssage("卡特林");
Console.ReadLine();
}
/// <summary>
/// Attribitefunc1 is class that provite a print method
/// </summary>
public class Attribitefunc1{
[Conditional("release")]
public static void printMesssage(string msg)
{
Console.WriteLine("輸出數據:"+ msg);
}
}
然后發現不會有任何輸出;
然后我加上#define release;
結果:
那么我們明白原來這個是否執行是根據是否預處理來判斷的,這使得我們程序變得很方便。
再舉一個例子:
我們在開發一個項目中,如果我們廢棄了代碼,我們是不會去立即刪除的,因為需要回顧歷史。
static void Main(string[] args)
{
Attribitefunc1.printMesssage("卡特林");
Console.ReadLine();
}
/// <summary>
/// Attribitefunc1 is class that provite a print method
/// </summary>
public class Attribitefunc1{
[Obsolete("this is old",true)]
public static void printMesssage(string msg)
{
Console.WriteLine("輸出數據:"+ msg);
}
}
這時候顯示的是:
當然有時候我們是不會讓他報錯的,只需要警告。
[Obsolete("this is old",false)]
好了,既然屬性這么好用不如我們就來自定義吧!
就用驗證來舉例子吧!
[AttributeUsage(AttributeTargets.Property,AllowMultiple =true,Inherited =true)]
public abstract class BaseAttribute:Attribute
{
public virtual string error { get; set; }
public abstract bool Validate(object value);
}
要實現屬性就要繼承屬性!
在屬性類上我們可以加一些特性,AttributeUsage。
比如說:
AttributeTargets 表示的是作用於什么位置,你可以限制是類或者屬性等等。
AllowMultiple 是否可以有多個屬性,因為驗證有驗證是否為空、驗證是長度等等,需要為true。
Inherited 這個是否可繼承,一般是可繼承的。
下面以不為空來舉例:
public class RequiredAttribute : BaseAttribute
{
public override string error {
get {
if (base.error != null)
{
return base.error;
}
return "屬性不能為空";
}
set { base.error = value;
}
}
public override bool Validate(object value)
{
return !(value == null);
}
}
上面我繼承了BaseAttribute,實現BaseAttribute里面的方法和屬性。
下面我又一個student類:
public class Student
{
private string name;
[Required]
public string Name { get => name; set => name = value; }
}
那么我給Name值不能為空的屬性。
同樣我們要去實現驗證過程,為了解耦,需要加一個helper類;
public class ValidateHelper
{
public static string Validate<T>(T t)
{
Type type = t.GetType();
PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in propertyInfos)
{
if (propertyInfo.IsDefined(typeof(BaseAttribute)))
{
foreach (BaseAttribute attribute in propertyInfo.GetCustomAttributes(typeof(BaseAttribute)))
{
if (!attribute.Validate(propertyInfo.GetValue(t, null)))
{
return attribute.error;
}
}
}
}
return null;
}
}
上面的原理非常簡單,就是遍歷一個泛型里面的屬性,找到里面的特性進行判斷。
我們需要書寫的判斷過程如下:
Student student = new Student();
var errormessage=ValidateHelper.Validate(student);
Console.WriteLine(errormessage);
Console.ReadKey();
得到的結果:
介紹完畢!