C# 高级特性(二)Attribute和反射

来源:互联网 发布:网站源码可以干吗 编辑:程序博客网 时间:2024/04/30 15:46

使用Attribute的时候大多需要用到反射,所以放在一起。

Attribute:

我的理解是,它可以给你的类、方法、字段等添加一些描述性语言,在运行期间又可以通过反射的方法获取它的内容。

在编译期间就初始化好了。

反射:

通过反射可以在不了解对象的内容时,操作对象。

优点:在运行的时候才需要获取对象内容,提示程序的灵活性,降低耦合等。

缺点:操作效率低,会暴露私有的属性和方法等。

举例:

我有一个父类Animal,他有四个子类:Cat、Dog、Lion、Tiger。

    public class Animal
    { }
    public class Cat : Animal
    { }
    public class Dog : Animal
    { }
    public class Lion : Animal
    { }
    public class Tiger : Animal
    { }

假设我们需要写一个方法,描述动物叫声的大小,我们认为Cat和Dog的叫声小,属于一类,Lion和Tiger的叫声大,属于一类。

如果不用Attribute和反射机制,那么我们需要给每个动物都定义叫声这个方法。但是,如果用Attribute和反射机制用的话,则,我们可以把Cat和Dog定义一个方法,Lion和Tiger定义一个方法。

定义一个自定义attribute:

    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class CallBindingAttribute : Attribute
    {
        private Type m_CallType;
        public Type CallType
        {
            get { return m_CallType; }
        }
        internal CallBindingAttribute(Type callType)
        {
            m_CallType = callType;
        }
    }

定义动物叫声:

    public class CallType
    {
        public enum Level
        {
            LOW = 1,
            HIGH = 2
        }


        private Level m_CallLevel;
        public Level CallLevel
        {
            get { return m_CallLevel; }
            internal set { m_CallLevel = value; }
        }
    }

定义大型动物和小动物叫声,并绑定我们自定义的属性:

    [CallBinding(typeof(Cat))]
    [CallBinding(typeof(Dog))]
    public class SmallAnimalType : CallType
    {
        public SmallAnimalType()
        {
            this.CallLevel = Level.LOW;
        }
    }


    [CallBinding(typeof(Lion))]
    [CallBinding(typeof(Tiger))]
    public class BigAnimalType : CallType
    {
        public BigAnimalType()
        {
            this.CallLevel = Level.HIGH;
        }
    }

通过反射获取合适动物叫声:

 public static List<CallType> Calls = new List<CallType>();
        public static List<CallType> GetFaultTypes(Type type)
        {
            List<CallType> cts = new List<CallType>();
            foreach (CallType ct in Calls)
            {
                object[] os = ct.GetType().GetCustomAttributes(typeof(CallBindingAttribute), false); // 反射方法,通过绑定的CallBindingAttribute和类获取到合适的叫声
                foreach (CallBindingAttribute dba in os)
                {
                    if (dba.CallType == type || type.IsSubclassOf(dba.CallType))
                    {
                        cts.Add(ct);
                        break;
                    }
                }
            }
            return cts;
        }

根据动物类型获取到动物叫声:

    SmallAnimalType sType = new SmallAnimalType(); // 加载动物叫声
    Calls.Add(sType);
     BigAnimalType bType = new BigAnimalType();
    Calls.Add(bType);
    Dog dog = new Dog();
     List<CallType> DogCall = GetFaultTypes(dog.GetType()); // 根据动物类型Dog获取狗的叫声
     foreach (CallType callType in DogCall)
     {
             Console.WriteLine(callType.CallLevel.ToString());  //输出为狮子的叫声  HIGH
     }

     List<CallType> LionCall = GetFaultTypes(lion.GetType());
     foreach (CallType callType in LionCall)
     {
             Console.WriteLine(callType.CallLevel.ToString());//输出为狗的叫声  LOW
     }

0 0
原创粉丝点击