posted at 2022.2.15 07:41 by administrator
特性是一种比较特殊的类,通常作为代码对象的附加部分,用于向运行时提供一些补充信息。特性一般有以下特征:
1、 从Attribute类派生。
2、 类型名称一般以Attribute结尾。尽管这不是语法规则,但开发者应该遵守这一约定,应用时可以将后缀省略。
3、 在声明特性时必须在类上应用AttributeUsage。AttributeUsage本身也是一个特性类,用于标注 当前声明的特性类应用于类、属性、结构或方法上。
4、 特性同样而具有构造函数。
5、 特性支持多实例,需要将AttributeUsage的AllowMultiple属性设置为true。
特性的作用是为代码对象应用一些辅助的信息,因此在应用程序运行阶段,可以检索特性的实例相关数据,对数据进行验证。
要实现在运行阶段检索特性,需要用到反射技术,即在运行时获取类型以及其成员相关的信息,然后再查找出已应用特性的对象。
通过Type类可以得到各种代码对象(类、方法、属性、字段等)的信息,它们的共同基类是MemberInfo,通过GetCustomAttribute扩展方法可以直接检索到已应用的特性实例。
【实例】
步骤1:新建一个控制台应用程序项目。
步骤2:声明一个特性类,并指定它只能应用于属性成员。
[AttributeUsage(AttributeTargets.Property)] public class MyAttribute : Attribute { public char StartChar { get; set; } public int MaxLen { get; set; } }
步骤3:声明一个测试类,并把MyAttribute应用到RawName属性上。
public class Test { [My(StartChar = 'k', MaxLen = 7)] public string RawName { get; set; } }
步骤4:在Program类中声明一个静态方法,在运行阶段验证Test对象的属性值是否满足MyAttribute实例中所设的限制。
static bool CheckTest(Test t, string property) { // 获取类型信息 Type type = t.GetType(); // 查找属性成员 PropertyInfo prop = type.GetProperty(property, BindingFlags.Public | BindingFlags.Instance); if (prop == null) { return false; } // 获取特性 MyAttribute att = prop.GetCustomAttribute<MyAttribute>(); // 获取实例的属性值 string value = prop.GetValue(t) as string; if (string.IsNullOrEmpty(value)) return false; // 进行验证 if (value.StartsWith(att.StartChar) == false) return false; if (value.Length > att.MaxLen) return false; return true; }
PropertyInfo类表示与属性相关的信息,调用它的GetValue方法可以获取属性当前值。将属性当前值与MyAttribute实例中指定的值相比较,可以验证属性值是否符合要求。
步骤5:在Main方法中实例化Test对象,为RowName属性设定一个初始值。
Test v = new Test { RawName = "guangbu" };
步骤6:调用CheckTest方法对以上Test实例的RawName属性进行验证。
bool b = CheckTest(v, nameof(Test.RawName)); if (b) Console.WriteLine("符合要求。"); else Console.WriteLine("不符合要求。");
虽然Test对象的RawName属性长度未超过7,但是以字符“g”开头,因此验证未通过。
附:C#全部源代码
using System;using System.Reflection; namespace Demo{ class Program { static void Main(string[] args) { Test v = new Test { RawName = "guangbu" }; // 调用方法进行属性值验证 bool b = CheckTest(v, nameof(Test.RawName)); if (b) Console.WriteLine("符合要求。"); else Console.WriteLine("不符合要求。"); Console.Read(); } static bool CheckTest(Test t, string property) { // 获取类型信息 Type type = t.GetType(); // 查找属性成员 PropertyInfo prop = type.GetProperty(property, BindingFlags.Public | BindingFlags.Instance); if (prop == null) { return false; } // 获取特性 MyAttribute att = prop.GetCustomAttribute<MyAttribute>(); // 获取实例的属性值 string value = prop.GetValue(t) as string; if (string.IsNullOrEmpty(value)) return false; // 进行验证 if (value.StartsWith(att.StartChar) == false) return false; if (value.Length > att.MaxLen) return false; return true; } } [AttributeUsage(AttributeTargets.Property)] public class MyAttribute : Attribute { public char StartChar { get; set; } public int MaxLen { get; set; } } public class Test { [My(StartChar = 'k', MaxLen = 7)] public string RawName { get; set; } }}
52b5fc09-65f0-45b9-a597-a97032be8eed|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: C#, 程序, 代码, 方法, 扩展方法, 类, 数据
IT技术