C# Attribute

C# Attribute

经常碰到使用Attribute的地方,但是基本没有自定义使用过,有时间稍稍学习理解下。

Attribute定义

Attribute本身是个类(Class),一个继承了System.Attribute的类。AttributeTargets枚举类型帮助确定Attribute适用对象。

    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredAttribute : System.Attribute
    {
    }

    [AttributeUsage(AttributeTargets.Property)]
    public class MaxStringLengthAttribute : System.Attribute
    {
        public int MaxLength;        
    }


    [AttributeUsage(AttributeTargets.Property)]
    public class StandardWeightAttribute : System.Attribute
    {
        public int MinWeight;
        public int MaxWeight;

        public StandardWeightAttribute(int minWeight, int maxWeight)
        {
            MinWeight = minWeight;
            MaxWeight = maxWeight;
        }
    }


    [AttributeUsage(AttributeTargets.Class)]
    public class ColorAttribute : System.Attribute
    {
        public FruitColor Color;
    }

Attribute使用

可以在类,属性,方法等上方通过[Attribute(parameter…)]的方式引用Attribute。
有构造方法的可以通过构造方法给属性赋值,没有加入构造方法的public属性可以通过[Attribute(parameter1, parameter2=value,…)]的方式给属性赋值。

    public class QualifiedFruit
    {
        [Required]
        [MaxStringLength(MaxLength = 32)]
        public string Name { get; set; }

        public decimal Price { get; set; }

        public virtual int Weight { get; set; }

        public FruitColor Color { get; set; }
    }

    [Color(Color = FruitColor.YELLOW)]
    public class QualifiedYellowKiWiFruit : QualifiedFruit
    {

        [StandardWeight(100, 120)]
        public override int Weight { get => base.Weight; set => base.Weight = value; }

    }

    [Color(Color = FruitColor.GREEN)]
    public class QualifiedGreenKiWiFruit : QualifiedFruit
    {

        [StandardWeight(120, 150)]
        public override int Weight { get => base.Weight; set => base.Weight = value; }

    }

    public enum FruitColor
    {
        RED,
        GREEN,
        YELLOW
    }

写个验证方法,或者扩展方法来验证Attribute。
Attribute基本通过反射的方式去获取。

    public static class QualifiedFruitExt
    {
        public static bool IsStandard(this QualifiedFruit fruit)
        {
            var fruitType = fruit.GetType();
            var attrs = fruitType.GetCustomAttributes(false);

            // ColorType check
            foreach(var attr in attrs)
            {
                if(attr.GetType().Name == typeof(ColorAttribute).Name)
                {
                    var color = ((ColorAttribute)attr).Color;
                    if(color != fruit.Color)
                    {
                        return false;
                    }
                }
            }

            // Name check
            var propName = fruitType.GetProperty("Name");
            var propNameAttrs = propName.GetCustomAttributes(true);
            foreach(var attr in propNameAttrs)
            {
                if(attr.GetType().Name == typeof(RequiredAttribute).Name)
                {
                    if (string.IsNullOrEmpty(fruit.Name))
                    {
                        return false;
                    }
                }

                if(attr.GetType().Name == typeof(MaxStringLengthAttribute).Name)
                {
                    var maxLength = ((MaxStringLengthAttribute)attr).MaxLength;
                    if(!string.IsNullOrEmpty(fruit.Name) && fruit.Name.Length > maxLength)
                    {
                        return false;
                    }
                }
            }

            // Weight check
            var propWeight = fruitType.GetProperty("Weight");
            var propWeightAttrs = propWeight.GetCustomAttributes(true);
            foreach (var attr in propWeightAttrs)
            {
                if (attr.GetType().Name == typeof(StandardWeightAttribute).Name)
                {
                    var min = ((StandardWeightAttribute)attr).MinWeight;
                    var max = ((StandardWeightAttribute)attr).MaxWeight;
                    if (fruit.Weight > max || fruit.Weight < min)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
    }

做一个简单的验证。

    static void Main(string[] args)
    {
        QualifiedFruit fruit1 = new QualifiedGreenKiWiFruit
        {
            Name = "Super Delicious",
            Price = 1000.00m,
            Weight = 220,
            Color = FruitColor.GREEN
        };
        var isStandard = fruit1.IsStandard();
    }

Attribute使用场景

.Net MVC下面有不少Attribute的使用场景,像DataAnnotationsMVC库下的一些Attribute,还需要进一步学习。

问题

1.为什么使用Attribute?
找了些回答,大体意思是做第三方包的时候去用。这些工具包不关心你的业务逻辑,它们处理一些共通的东西,并且需要在运行时通过反射来做这些事。
不知道自己程序内部有哪些运用Attribute的好的场景。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值