c#特性(Attribute)学习总结2

通过特性提供额外行为的实例:自定义特性做数据验证(效验属性值的大小和非空)

学生类中有个QQ的属性,效验QQ不能小于100000(5位数),不能大于999999999999(12位数),并且QQ的属性不能为空。如果满足这些效验返回true,否则返回false。

声明一个抽象类,所有的自定义特性都继承自这个抽象类,为了确保自定义特性都实现数据效验的方法。

    /// <summary>
    /// 抽象类 基类
    /// </summary>
    public abstract class AbstractVaildDataAttribute : Attribute
    {
        /// <summary>
        /// 验证数据是否符合要求
        /// </summary>
        /// <param name="oValue"></param>
        /// <returns></returns>
        public abstract bool ValidData(object oValue);
    }

声明效验属性非空的特性:

    /// <summary>
    /// 声明一个可以对属性应用 空字符串效验的特性
    /// 效验值是否为空
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class RequireAttribute : AbstractVaildDataAttribute
    {
        public override bool ValidData(object oValue)
        {
            return !string.IsNullOrEmpty(oValue.ToString());
        }
    }

声明效验属性值大小的特性:

    /// <summary>
    /// 声明一个可以对属性应用LongAttribute的特性
    /// 效验值的范围
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class LongAttribute : AbstractVaildDataAttribute
    {
        private long _Min = 0;
        private long _Max = 0;

        public LongAttribute(long min, long max)
        {
            _Min = min;
            _Max = max;
        }

        public override bool ValidData(object oValue)
        {
            long lValue = 0;
            return oValue != null && long.TryParse(oValue.ToString(), out lValue) && lValue >= _Min && lValue <= _Max;
        }
    }

 声明一个学生类,并在属性上面添加上自定义的两个特性(‘Long’,‘Require’):

 public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }

        [Long(10000, 999999999999)]
        [Require]
        public long QQ { get; set; }

    }
扫描二维码关注公众号,回复: 12574609 查看本文章

声明一个扩展方法,用于调用反射来效验属性的值:

        /// <summary>
        /// 效验属性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool ValidDataExtend<T>(this T t) {
            Type type = t.GetType();
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(AbstractVaildDataAttribute),true))
                {
                    object oValue = prop.GetValue(t);//获取要校验类型的值
                    object[] oAttributeArr = prop.GetCustomAttributes(typeof(AbstractVaildDataAttribute), true);//获取所有自定义的特性
                    foreach (AbstractVaildDataAttribute attr in oAttributeArr)
                    {
                        if (!attr.ValidData(oValue))
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

调用扩展方法,验证特性效果:

      static void Main(string[] args)
        {
            Student student = new Student()
            {
                Id = 1,
                Name = "张三",
                QQ = 1234565555
            };

            if (student.ValidDataExtend())
            {
                Console.WriteLine("效验通过");
            }
            else
            {
                Console.WriteLine("效验不通过");
            }

            Console.ReadKey();
        }

 执行结果:

整体实现思路:

1.声明抽象类(基类)

2.声明非空效验特性和数值大小效验特性 

3.在属性上面应用特性

4.使用反射访问特性,效验数值是否符合要求

猜你喜欢

转载自blog.csdn.net/liangmengbk/article/details/112792035