首页 > 其他 > 详细

【C#】属性(Attribute)

时间:2014-08-20 17:55:22      阅读:258      评论:0      收藏:0      [点我收藏+]

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

运用范围

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

  

bubuko.com,布布扣
 [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.

第三步:创建验证的类

bubuko.com,布布扣
 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一般都会和反射一起使用,这里验证了字符串长度是否超过所要求的,如果超过了则会抛出异常

bubuko.com,布布扣
   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

 

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

 

【C#】属性(Attribute),布布扣,bubuko.com

【C#】属性(Attribute)

原文:http://www.cnblogs.com/guochenkai/p/3925141.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!