特性attribute就是一個類,可以應用在程序集,類,屬性,方法等元素。
在運行的時候通過反射獲取特性attribute的信息。
下面示例是對屬性做Trim標記,可以在對象層面調用一次Trim(),就將標記了Trim特性的屬性作Trim()處理。
using System;
namespace ConsoleApp1
{
//定製特性,特性也是一個類,自定義特性須繼承System.Attribute
//AttributeUsage控制特性
[AttributeUsage(AttributeTargets.Property,//應用於屬性,
AllowMultiple = true,//允許應用多次
Inherited = false)]//不能繼承到派生類
public class TrimAttribute : Attribute
{
private readonly Type type;
//必須顯示定義構造函數
public TrimAttribute(Type type)
{
this.type = type;
}
public Type Type => this.type;
}
public static class TrimExtension
{
//拓展方法
public static void TrimProperties(this object obj)
{
//反射確定特性的信息
Type t = obj.GetType();
foreach (var pro in t.GetProperties())
{
foreach (var attr in pro.GetCustomAttributes(true))//返回用於此屬性的自定義特性
{
if (attr is TrimAttribute ta && ta.Type == typeof(string))//如果此屬性附加了Trim(typeof(string))的屬性
{
if (pro.GetValue(obj) != null)
{
pro.SetValue(obj, pro.GetValue(obj).ToString().Trim(), null);//trim屬性值
}
}
}
}
}
}
public class Test
{
[Trim(typeof(string))]//[]裏其實就是TrimAttribute的構造函數
public string testString1 { get; set; }
public string testString2 { get; set; }
[Trim(typeof(string))]
public string testString3 { get; set; }
}
class Program
{
static void Main(string[] args)
{
Test test = new Test() { testString1 = " testString1- ", testString2 = "testString2- ", testString3 = " testString3 " };
Console.WriteLine(test.testString1 + test.testString2 + test.testString3);
test.TrimProperties();
Console.WriteLine(test.testString1 + test.testString2 + test.testString3);
//看結果可以發現,Test類被標記了Trim特性的屬性都被Trim()。
Console.ReadKey();
}
}
}