zoukankan      html  css  js  c++  java
  • C#基础---Attribute(标签) 和 reflect(反射) 应用二

    背景: 【为了方便,自己还是模拟一个背景吧, 感觉不是很恰当,不过自己的Demo里面自己这样写的.当然跟公司的比起来肯定不够完善】

    每个人都会吃饭,可是每个国家吃饭的习惯不一样。中国人吃汤圆,加拿大人吃意大利面,美国人吃火鸡。还有其他国家的人吃其他东西。如何来维护不同国家的不同习俗呢。我开了一家饭店,目前有中国,美国,加拿大的食物,如果来了一个人,我们如何让程序自动通过该人的国籍,来判断他是要吃什么呢。 这就要靠打标签和反射来解决了。下面来看Demo吧.

    1.实体类.

    首先我们定义一个基类,Person基类里面定义虚拟方法,每个人都会吃东西。

    Person(Country=PersonCountry.UNKnown)]
        public class Person
        {
            public virtual void Eat()
            {
                Console.WriteLine("我们吃东西");
            }
        }

    再次,不同国家的人, 去继承基类,重写eat方法,体现不同国家的吃饭习惯.

    [Person(Country=PersonCountry.USA)]
    public class USA : Person
    {
    	public override void Eat()
    	{
    		Console.WriteLine("我们吃火鸡");
    	}
    }
    [Person(Country=PersonCountry.China)]
    public class Chinese : Person
    {
    	public override void Eat()
    	{
    		Console.WriteLine("我们吃汤圆");
    	}
    }
    [Person(Country=PersonCountry.USA)]
    public class USA : Person
    {
    	public override void Eat()
    	{
    		Console.WriteLine("我们吃火鸡");
    	}
    }
    

    2.标签

    为了区分每一个类具体是哪个国家的人,我们设置了一个Person标签,和PersonCountry枚举

    public class PersonAttribute:Attribute
    {
    	private PersonCountry _country = PersonCountry.UNKnown;
    	public PersonCountry Country
    	{
    		get
    		{
    			return _country;
    		}
    		set
    		{
    			this._country = value;
    		}
    	}
    }
    public enum PersonCountry
    {
    	USA,
    	China,
    	Canada,
    	UNKnown
    }
    

    3. Helper方法:

    实体类和枚举已经定义好。 那如何让程序自动区分,人的国籍,然后确认他们的吃饭习惯呢。下面可以通过反射来判断.

    A. Assembly.GetExecutingAssembly() 可以获取当前的程序级,assembly.GetTypes() 获取所有的类型,包括USA,Canda,Chinese 信息

    B. (PersonAttribute)Attribute.GetCustomAttribute(currentType, typeof (PersonAttribute));获取当前类的标签,然后用标签与传进来的countryType进行比较,确认Person类型.

    C. 然后通过InvokeMember来创建对象,返回

    public class PersonHelper
    {
    	public static Person GetPersonObj(PersonCountry contryType)
    	{
    		Assembly assembly = Assembly.GetExecutingAssembly();
    		Type[] typeList = assembly.GetTypes();
    		foreach (Type currentType in typeList)
    		{				
    			var attribute = (PersonAttribute)Attribute.GetCustomAttribute(currentType, typeof(PersonAttribute));
    			if (attribute!=null && attribute.Country == contryType)
    			{
    				return currentType.InvokeMember(null, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, new object[] { }) as Person;
    			}				 
    		}
    		return new Person();
    	}
    }
    

    4. 测试方法:

    可能前面大家迷迷糊糊,下面来看看测试,可能会比较明白:

    Note: 1. 如果新进来的人,是中国人,只需要调用Helper方法然后获取到Chinese对象,然后执行对应的eat方法。

    2. 如果本店想知道韩国人的吃饭习惯,只需要多增加一个类,然后打上对应的标签就OK了。

    public static void Main(string[] args)
            {
                Person p1 = PersonHelper.GetPersonObj(PersonCountry.China);
                p1.Eat(); //输出:我们吃汤圆
     
                Person p2 = PersonHelper.GetPersonObj(PersonCountry.Canada);
                p2.Eat(); //输出:我们吃意大利面
            }        

    5.总结:

    本博客描述的例子很牵强,不过只是感觉这种想法还是不错的。方便项目的扩展。希望对大家有用。同时也是自己为了回顾一下反射
  • 相关阅读:
    Codeforces 每日一练 1213G+961E+1282B2
    AtCoder Beginner Contest 161题解
    Codeforces每日一练 495B+55C+1280C
    CF1062E 线段树/LCA
    Codeforces Round #697 (Div. 3) 题解
    Codeforces Round #511 (Div. 2) A~D题解
    Atcoder ABC 189 题解
    CF1093G 高维曼哈顿距离/线段树
    CF1117D Magic Gems 矩阵快速幂 DP
    CF1106E Lunar New Year and Red Envelopes DP
  • 原文地址:https://www.cnblogs.com/sjqq/p/6889100.html
Copyright © 2011-2022 走看看