C#特性

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; }
    }
}

 

Tags: , , , , , ,

IT技术

添加评论

  Country flag

biuquote
  • 评论
  • 在线预览
Loading