1. 程式人生 > WINDOWS開發 >c# 屬性類(特性)

c# 屬性類(特性)

前言

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();

得到的結果:

技術分享圖片

介紹完畢!