【C#】属性(Attribute)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 【C#】属性(Attribute)

【C#】属性(Attribute)

 2014/8/20 19:02:55  Eric Guo  程序员俱乐部  我要评论(0)
  • 摘要:如果程序员是猫,你是哪只猫?这个是我一直都很喜欢的一个技术,不是很麻烦,也不是很难理解,和反射配合起来,只有你想不到没有做不到的用途(夸张了哈)。运用范围程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute[AttributeUsage(AttributeTargets.All)]publicclassTestAttribute:Attribute{
  • 标签:C#

如果程序员是猫,你是哪只猫?

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

运用范围

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

  

class="code_img_closed" src="/Upload/Images/2014082019/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('b6225db6-b50a-4c04-ab75-f57cf782ca49',event)" src="/Upload/Images/2014082019/2B1B950FA3DF188F.gif" alt="" />
 [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

 

补充材料:

 

发表评论
用户名: 匿名