C#基础---Attribute(标签) 和 reflect(反射) 应用二

  以前我有写过一篇有关,打标签和反射的应用,主要用于类中字段的验证。下面是连接 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.总结:

本博客描述的例子很牵强,不过只是感觉这种想法还是不错的。方便项目的扩展。希望对大家有用。同时也是自己为了回顾一下反射和打标签的用法,才打算写这篇博客的。

  

  

时间: 2024-10-15 16:22:39

C#基础---Attribute(标签) 和 reflect(反射) 应用二的相关文章

C#基础--Attribute(标签) 和 reflect(反射) 应用

1.Attribute的定义与作用: 公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法和属性等.Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为.比如在WCF中常用的序列化.比如添加的[DataMenber]就是一种标签.以及xml序列化也是一样的. 2.Reflect的定义与作用 反射可以用于观察并修改程序在运行

复习java基础第七天(反射)

一:目标 Ø理解 Class 类 Ø理解 Java 的类加载机制 Ø学会使用 ClassLoader 进行类加载 Ø理解反射的机制 Ø掌握 Constructor.Method.Field 类的用法 Ø理解并掌握动态代理 1.Class类 –对象照镜子后可以得到的信息:某个类的数据成员名.方法和构造器.某个类到底实现了哪些接口. 对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象. 一个 Class 对象包含了特定某个类的有关信息. –  Class 对象只能由系统建立对象.

h5标签基础 meta标签

<meta>标签位于<head>标签里面,具体作用有如下: 1.设置网页编码 eg: <meta charset="utf-8"/>  ,//utf-8是包含了全世界字符的一个编码集合,例如一个中文网站在国外搭建后依旧不会乱码,会使用英文显示出来 2.增强Seo ,百度抓取强度 · <meta name="keywords" content="h5基础,h5标签meta的使用,h5增加抓取强度"/>

原始套接字基础(原始套接字系列二)

在进入Raw Socket多种强大的应用之前,我们先讲解怎样建立一个Raw Socket及怎样用建立的Raw Socket发送和接收IP包. 建立Raw Socket 在Windows平台上,为了使用Raw Socket,需先初始化WINSOCK: // 启动 WinsockWSAData wsaData;if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0){ cerr << "Failed to find Winsock 2.1 or

跟王老师学反射(二):Java类的加载、连接和初始化

跟王老师学反射(二):Java类的加载.连接和初始化 主讲教师:王少华   QQ群号:483773664 学习内容: 了解类的加载.连接和初始化 一.类的生命周期 当我们编写一个java的源文件后,经过编译会生成一个后缀名为class的文件,这种文件叫做字节码文件,只有这种字节码文件才能够在java虚拟机中运行,java类的生命周期就是指一个class文件从加载到卸载的全过程.一个java类的完整的生命周期会经历加载.连接.初始化.使用.和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直

.net Reflection(反射)- 二

反射 Reflection 中访问方法 新建一个ClassLibrary类库: public class Student { public string Name { get; set; } public string School { get; set; } public int Sum(int a, int b) { return a + b; } public string GetName() { return "this is book" ; } } /// <summa

GO_09:GO语言基础之reflect反射

反射reflection 1. 反射可以大大的提高程序的灵活性,使得 interface{} 有更大的发挥余地 2. 反射使用 TypeOf 和 ValueOf 函数从接口中获取目标对象信息 3. 反射会将匿名字段作为独立字段(匿名字段本质) 4. 想要利用反射修改对象状态,前提是 interface.data 是 settable,即 pointer-interface 5. 通过反射可以"动态"调用方法 示例一: 举例说明反射使用 TypeOf 和 ValueOf 来取得传入类型的

Java基础学习笔记【12】Reflect反射(2)

使用反射来创建对象(1)public T newInstance():只能创建非private,无参的构造方法的对象:好比 new 类() 1 2 Class<Teacher> clz = Teacher.class; Teacher t2 = clz.newInstance(); (2)先得到一个构造器,调用构造器里的一个方法, T newInstance(Object... initargs) . initargs表示构造器的需要的实际参数 1 2 3 Constructor<Tea

Java基础学习笔记【11】Reflect反射(1)

InputStreamReader将字节流转换为字符流 在java1.7中新增了Files,Paths对流,路径操作的工具类,内部就是输入输出流等的操作 Syso加只能提示可以快速代码System.out.println(): 反射创建Class的三种方式:(1)使用 class的属性得到Class对象 1 2 Class<String> c = String.class;//String.class就表示JVM里的一份表示String类的字节码 Class<String> c2