• 【C#】属性(Attribute)


    这个是我一直都很喜欢的一个技术,不是很麻烦,也不是很难理解,和反射配合起来,只有你想不到没有做不到的用途(夸张了哈)。

    运用范围

    程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute

      

     [AttributeUsage(AttributeTargets.All)]
        public class TestAttribute : Attribute
        {
        }
        [TestAttribute]//结构
        public struct TestStruct { }
        
        [TestAttribute]//枚举
        public enum TestEnum { }
    
    
        [TestAttribute]//类上
        public class TestClass
        {
            [TestAttribute]
            public TestClass() { }
            
            [TestAttribute]//字段
            private string _testField;
    
            [TestAttribute]//属性
            public string TestProperty { get; set; }
    
            [TestAttribute]//方法上
            [return: TestAttribute]//定义返回值的写法
            public string TestMethod([TestAttribute] string testParam)//参数上
            {
                throw new NotImplementedException();
            }
        }
    View Code

    这里我们给出了除了程序集和模块以外的常用的Atrribute的定义。

     自定义Attribute

    为了符合“公共语言规范(CLS)”的要求,所有的自定义的Attribute都必须继承System.Attribute。

    第一步:自定义一个检查字符串长度的Attribute

        [AttributeUsage(AttributeTargets.Property)]
        public class StringLengthAttribute : Attribute
        {
            private int _maximumLength;
            public StringLengthAttribute(int maximumLength)
            {
                _maximumLength = maximumLength;
            }
    
            public int MaximumLength
            {
                get { return _maximumLength; }
            }
        }

    AttributeUsage这个系统提供的一个Attribute,作用来限定自定义的Attribute作用域,这里我们只允许这个Attribute运用在Property上,内建一个带参的构造器,让外部传入要求的最大长度。

    第二步:创建一个实体类来运行我们自定义的属性

     public class People
        {
            [StringLength(8)]
            public string Name { get; set; }
    
            [StringLength(15)]
            public string Description { get; set; }
        }

    定义了两个字符串字段Name和Description, Name要求最大长度为8个,Description要求最大长度为15.

    第三步:创建验证的类

     public class ValidationModel
        {
    
            public void Validate(object obj)
            {
                var t = obj.GetType();
    
                //由于我们只在Property设置了Attibute,所以先获取Property
                var properties = t.GetProperties();
                foreach (var property in properties)
                {
    
                    //这里只做一个stringlength的验证,这里如果要做很多验证,需要好好设计一下,千万不要用if elseif去链接
                    //会非常难于维护,类似这样的开源项目很多,有兴趣可以去看源码。
                    if (!property.IsDefined(typeof(StringLengthAttribute), false)) continue;
    
                    var attributes = property.GetCustomAttributes();
                    foreach (var attribute in attributes)
                    {
                        //这里的MaximumLength 最好用常量去做
                        var maxinumLength = (int)attribute.GetType().
                            GetProperty("MaximumLength").
                            GetValue(attribute);
    
                        //获取属性的值
                        var propertyValue = property.GetValue(obj) as string;
                        if (propertyValue == null)
                            throw new Exception("exception info");//这里可以自定义,也可以用具体系统异常类
    
                        if (propertyValue.Length > maxinumLength)
                            throw new Exception(string.Format("属性{0}的值{1}的长度超过了{2}", property.Name, propertyValue, maxinumLength));
                    }
                }
    
            }
        }
    View Code

    这里用到了反射,因为Attribute一般都会和反射一起使用,这里验证了字符串长度是否超过所要求的,如果超过了则会抛出异常

       private static void Main(string[] args)
            {
    
                var people = new People()
                {
                    Name = "qweasdzxcasdqweasdzxc",
                    Description = "description"
                };
    
                try
                {
                    new ValidationModel().Validate(people);
                }
                catch (Exception ex)
                {
    
                    Console.WriteLine(ex.Message);
                }
                Console.ReadLine();
    
            }
    View Code

    基础篇不涉及很多高级用法,这个明白以后,变化可以很多。

  • 相关阅读:
    Exp4 恶意代码分析
    实验一 密码引擎4国䀄算法交叉测试(选做)
    我 邀请 C++ 吧 吧主 @cqwrteur 加入 开源项目 ILBC
    协程 的 主要作用 是 让 单核 GC 变成 单线程 GC
    测量 绝对速度 的 方法
    数学吧 《这个谬论应该怎么反驳》
    民科吧 的 @湿芋 出了 一题 u = x y^2 z
    rdkafka模块
    使用相似矩阵对伴奏和人声进行划分 MUSIC/VOICE SEPARATION USING THE SIMILARITY MATRIX
    ByteTrack论文精读
  • 原文地址:https://www.cnblogs.com/guochenkai/p/3925141.html
Copyright © 2020-2023  润新知