一、简介
记录一下特性的使用方法,特性其实就是一个特殊的类,需要继承Attribute,当我们序列化一个对象时,就需要在其类上标注Serializable,这个就是官方提供的一种特性
二、使用
2.1 定义
[AttributeUsage(AttributeTargets.All)]//约束特性使用范围
public class TestAttribute:Attribute//自定义特性类需要继承于Attribute
{
}
2.2 特性类的特点
特性类与普通类相似,可以包含属性,字段,方法等
[AttributeUsage(AttributeTargets.All)]//约束特性使用范围
public class TestAttribute:Attribute//自定义特性类需要继承于Attribute
{
public int TestProp { get; set; }
public string TestField;
public void Show()
{
Console.WriteLine("特性中的方法");
}
}
2.3 使用特性标记
[TestAttribute(TestProp = 11,TestField = "字段")]
public class Test
{
public string Name { get; set; }
}
2.4 标记好特性之后应该怎么用呢
Test test = new Test();
Type type = test.GetType();
if(type.IsDefined(typeof(TestAttribute), true))//是否被TestAttribute标记,包括它的父类被标记也算
{
object[] attr = type.GetCustomAttributes(typeof(TestAttribute), true);//获取标记该类型的所有TestAttribute特性
foreach (TestAttribute attribute in attr )//遍历所有的TestAttribute 特性
{
int prop = attribute.TestProp;
string fie = attribute.TestField;
attribute.Show();
}
}
2.5 拿到了之后又有什么用呢
目前我只用到了导出数据到excel时,标注其列名
[AttributeUsage(AttributeTargets.Property)]
public class TitleAttibute : Attribute
{
public string Title;
}
public class Order
{
private string _date;
[TitleAttibute(Title = "订单创建日期")]
public string Date
{
get { return _date; }
set { _date = value; }
}
private string _shift;
[TitleAttibute(Title = "班次")]
public string Shift
{
get { return _shift; }
set { _shift = value;}
}
}
导出数据时
Type type = obj.GetType();
List<PropertyInfo> propList = type.GetProperties().
Where(c => c.IsDefined(typeof(TitleAttibute), true)).ToList();//找被标记的属性
for (int i = 0; i < propList.Count; i++)//遍历所有被标记的属性,
{
TitleAttibute properAttribute = propList[i].
GetCustomAttribute<TitleAttibute>();
ICell cell = titleRow.CreateCell(i);
cell.SetCellValue(properAttribute.Title);//设置列名为标记值
}
2.6 其他的用法
比如做数据验证,结合反射,功能更加强大
[AttributeUsage(AttributeTargets.Property)]
public class DeviceAttribute : Attribute
{
public int DeviceIdLen { get; set; }
public bool Validate(string deviceid)
{
return deviceid!= null && deviceid.Lenght == DeviceIdLen ;
}
}
该特性用于检测要上传数据库的资产编号长度是否符合要求
public class ModelInfo
{
[DeviceAttribute(DeviceIdLen = 22)]
public string DeviceId{ get; set; }
}
public static class DataCheck
{
public static bool Validate<T>(this T t) where T : class
{
Type type = t.GetType();
foreach (var prop in type.GetProperties())
{
if (prop.IsDefined(typeof(DeviceAttribute ), true))
{
object obj= prop.GetValue(t);
foreach (DeviceAttribute attribute in prop.GetCustomAttributes(typeof(DeviceAttribute ), true))
{
if(!attribute.Validate(obj))
{
return false;
}
}
}
}
return true;
}
}
调用扩展方法验证数据合格性
ModelInfo mo = new();
mo.DeviceId = "20120810153131513";
bool isOk = mo.Validate();