Attribute

Attribute的作用是为元数据添加内容,即可用来标注一段程序,可以是类,属性,方法等。可利用反射机制获取标注或者获取标注的属性,类或者方法等,用来执行不同的操作,例如数据的校验等。

自定义特性

类名必须以Attribute结尾,需要继承.NET提供的Attribute抽象类。

C#中的 字段(Field)与属性(Property)

  • 字段是值私有属性。

  • 属性是指访问器,含get{}或set{}的代码块的特殊“方法”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 // 定义特性可以使用的目标
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,AllowMultiple = true)]
class LengthAttribute : Attribute
{
public int MinimumLength { get; set; }
public int Maximum { get; set; }

public LengthAttribute(int minimumLength, int maximum)
{
MinimumLength = minimumLength;
Maximum = maximum;
}

// 验证特性
public bool Validate(object value)
{
if (!string.IsNullOrWhiteSpace((string)value))
{
if(value.ToString().Length>= MinimumLength && value.ToString().Length <= Maximum)
{
return true;
}
}
return false;
}
}

验证特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Validatettribute
{
public static bool Validate<T>(T t)
{
// 获取所有属性
var propertyInfos = typeof(T).GetProperties();
// 遍历所有属性
foreach(var property in propertyInfos)
{
// 判断特性是否定义(注:多个特性可以继承自一个抽象类,直接判断抽象类是否定义)
if (property.IsDefined(typeof(LengthAttribute), true))
{
// 获取属性上的所有特性
var attributes = property.GetCustomAttributes();
// 遍历所有特性
foreach(var attribute in attributes)
{
LengthAttribute lengthAttribute = (LengthAttribute)attribute;
// 调用特性的验证方法 传入属性的值
return lengthAttribute.Validate(property.GetValue(t));
}
}
}
return false;
}
}

使用特性

1
2
3
4
5
6
public class Student
{
public int Id { get; set; }
[Length(1,50)]// 字符串长度校验
public string Name { get; set; }
}
1
2
3
4
5
6
7
8
9
10
class Program
{
static void Main(string[] args)
{
Student stu = new Student { Name = "" };
Console.WriteLine(Validatettribute.Validate<Student>(stu));// False
Student stu1 = new Student { Name = "zhang" };
Console.WriteLine(Validatettribute.Validate<Student>(stu1));// True
}
}