c# 屬性類(特性)
阿新 • • 發佈:2020-05-01
前言
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();
得到的結果:
介紹完畢!