首页 > 代码库 > 【C#】属性(Attribute)

【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 = http://www.mamicode.com/property.GetValue(obj) as string;                    if (propertyValue =http://www.mamicode.com/= 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

 

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