特性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();
}
}
}