C#之特性🔥
# 什么是特性
在C#中,特性(Attributes)是用于在程序中添加元数据和声明性信息的一种方式。它们允许您在声明代码的时候添加一些额外的信息,这些信息可以被编译器、运行时和其他工具所利用。特性可以应用于各种元素,包括程序集、模块、类型、成员和参数等。特性是继承自 Attribute 基类的类。 所有继承自 Attribute 的类都可以用作其他代码块的一种“标记”。 例如,有一个名为 ObsoleteAttribute 的特性。 此特性示意代码已过时,不得再使用。 将此特性应用于类(比如说,使用方括号)。
[Obsolete]
public class MyClass
{
}
2
3
4
虽然此类的名称为 ObsoleteAttribute,但只需在代码中使用 [Obsolete]。 大多数 C# 代码都遵循此约定。 如果愿意,也可以使用全名 [ObsoleteAttribute]。
# 自定义特性
通过定义继承自 Attribute 基类的新类来创建特性,如
public class MyAttribute:Attribute
{
public MyAttribute(string Title)
{
this.Title = Title;
}
public string Title { get; set; }
}
2
3
4
5
6
7
8
9
# 特性的范围(AttributeUsage)
创建特性类时,C# 默认允许对所有可能的特性目标使用此特性。 如果要将特性限制为只能用于特定目标,可以对特性类使用 AttributeUsageAttribute 来实现。 没错,就是将特性应用于特性! AttributeUsageAttribute的第一个参数必须是 AttributeTargets 枚举的一个或多个元素
[AttributeUsage(AttributeTargets.Property.Class |AttributeTargets.Property | AttributeTargets.Field)]
public class MyAttribute:Attribute
{
public MyAttribute(string Title)
{
this.Title = Title;
}
public string Title { get; set; }
}
2
3
4
5
6
7
8
9
10
上面的特性可应用于类,属性或字段,除了这些,还可以应用于接口、结构体、枚举等等。
如果AllowMultiple参数为 true,那么该特性可多次应用于单个实体,
[AttributeUsage(AttributeTargets.Property.Class,AllowMultiple = true)]
public class MyAttribute:Attribute
{
public MyAttribute(string Title)
{
this.Title = Title;
}
public string Title { get; set; }
}
2
3
4
5
6
7
8
9
10
[My("Test1")]
[My("Test2")]
class Class1 { }
//或者
[My("Test1"),My("Test2")]
class Class1 { }
2
3
4
5
6
如果 Inherited 是 false,则派生类不会继承特性。
[AttributeUsage(AttributeTargets.Property.Class,Inherited = false)]
public class MyAttribute:Attribute
{
public MyAttribute(string Title)
{
this.Title = Title;
}
public string Title { get; set; }
}
2
3
4
5
6
7
8
9
10
[My("Test")]
class BClass { }
class DClass : BClass { }
2
3
4
5
# 案例
下面是一个简单的用于校验字符串长度的特性示例:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StringLengthValidationAttribute : Attribute
{
private readonly int _maxLength;
public StringLengthValidationAttribute(int maxLength)
{
_maxLength = maxLength;
}
public bool IsValid(string value)
{
return value.Length <= _maxLength;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这个特性名为 StringLengthValidationAttribute,它继承自 Attribute 类。它具有一个构造函数,用于传入最大长度,并且有一个名为 IsValid 的方法,用于校验字符串的长度是否符合要求。可以将这个特性应用于类的属性或字段上,并在需要时使用 IsValid 方法进行校验。
假设有一个类 Person,其中包含一个名为 Name 的属性,使用StringLengthValidationAttribute 特性,并在运行时进行校验。首先,定义 Person 类:
public class Person
{
[StringLengthValidation(10)]
public string Name { get; set; }
}
2
3
4
5
然后,使用反射来检查 Person 类中的属性,并应用特性并进行校验:
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Name = "John Doe";
PropertyInfo property = typeof(Person).GetProperty("Name");
var attributes = property.GetCustomAttributes(typeof(StringLengthValidationAttribute), true);
if (attributes.Length > 0)
{
var validationAttribute = (StringLengthValidationAttribute)attributes[0];
if (!validationAttribute.IsValid(person.Name))
{
Console.WriteLine("Name exceeds maximum length.");
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
在这个示例中,我们首先获取 Person 类型的 Name 属性,并检查是否存在 StringLengthValidationAttribute 特性。如果存在,我们获取该特性的实例,并使用 IsValid 方法来检查属性值是否符合规定的长度。