C#反射Reflection学习

这篇帖子真的憋了好久.无处下笔啊!
搜了搜园子,已经有棵这方面的好白菜了!链接如下
http://www.cnblogs.com/whxleem/category/4641.html

以此为资料,学习了一下,但心有不甘,要不前两篇许下的承诺就没法实现了!于是有了这篇帖子.

【正文】
①什么是反射?
反射提供了封装程序集、模块和类型的对象。
您可以使用 反射动态地创建类型的实例( 见④ ), 将类型绑定到现有对象(这个不会),或从现有对象中获取类型( 见②③ )。然后,可以调用类型的方法或访问其字段和属性。
最最简单的反射:如下
 1 using  System;
 2 using  System.Reflection;
 3 namespace  TestReflection
 4 {
 5    class Program
 6    {
 7        static void Main(string[] args)
 8        {
 9            //创建两个对象【object和Objetct好像没有区别啊??连提示都一样!】
10            object A = new AX();
11            Object B = new AXzhz();
12            //获取对象的类型
13            new TestObjectType().TestObjectTypeNow(A, B);            
14        }

15    }

16
17    class AX
18    {
19    }

20
21    class AXzhz
22    {
23    }

24
25    class TestObjectType
26    {
27        //构造函数的默认修饰为private
28        internal void TestObjectTypeNow(object A, object B)
29        {
30            Type tpA = A.GetType();
31            Type tpB = B.GetType();
32            Console.WriteLine(tpA.FullName);
33            Console.WriteLine(tpB.FullName);
34            Console.ReadLine();
35        }

36    }

37}

输出结果:
TestReflection.AX
TestReflection.AXzhz
【分析】通过对象实例(A,B),可以使用GetType()方法获取该对象属于哪个类. 非类型转化后的类,而是构造该类型的类
【应用】给个变量/对象实例,测试下它属于哪个类,顺带还给出该类所属的Assembly
【附】另外一种 获取类型的方法是通过Type.GetType以及Assembly.GetType方法,如:
       Type t = Type.GetType("TestReflection.AX");
    需要注意的是,前面我们讲到了命名空间和装配件的关系,要查找一个类,必须指定它所在的装配件
Type类:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。     发晕,对泛型没研究.

②我们获得的Type实例有什么用?
   ⅰ获得类名:如上面例子的FullName属性,返回TestReflection.AX
       这个也比较恶心,直接用A.ToString();返回的也是这个结果.
   ⅱ创建该类的对象. 你首先通过ⅰ来获得类名AX
       AX ax = (AX)Activator.CreateInstance(tpA);
       都知道是AX类型了,怎么不new一个???鸡肋的东西.
      上面的【附】真不知道是干嘛吃的,都知道了类TestReflection.AX,直接new一个就可以了.
    ⅲ获得对象所属类的相关信息
         通过tpA的相关属性,来得到该类的相关信息.
         其实你通过A的相关属性,也可以得到该类的相关信息.还简单省事,真不知道Type类到底是干嘛吃的.

窥一斑而知全豹,一个对象实例泄漏的密秘(这个比较爽)
通过一个对象实例,我们可以获得包含这个对象实例的类的Assembly,进而获得整个Assembly的信息.

 1 using  System;
 2 using  System.Reflection;
 3 namespace  TestReflection
 4 {
 5    class Program
 6    {
 7        public static void Main(string[] args)
 8        {
 9            object A = new AX();
10            //获取对象所属的Assembly的所有类的基本信息
11            new TestObjectType().TestObjectTypeNow(A);
12        }

13    }

14
15    class AX
16    {
17        internal int kkkkkkkk = 0;
18        public int ooooooooo;
19        private int property;
20
21        public int Property
22        {
23            get return property; }
24            set { property = value; }
25        }

26        public void A()
27        {
28            Console.WriteLine("AX's function!~");
29        }

30    }

31
32    class AXzhz
33    {
34    }

35
36    class TestObjectType
37    {
38        //构造函数的默认修饰为private
39        internal void TestObjectTypeNow(object A)
40        {
41            Type tpA = A.GetType();
42            Assembly assembly = tpA.Assembly;
43            Type[] types = assembly.GetTypes();
44            foreach (Type type in types)
45            {
46                Console.WriteLine("【类名】"+type.FullName);
47                //获取类型的结构信息
48                ConstructorInfo[] myconstructors = type.GetConstructors();
49                Show(myconstructors);
50                //获取类型的字段信息
51                FieldInfo[] myfields = type.GetFields();
52                Show(myfields);
53                //获取方法信息
54                MethodInfo[] myMethodInfo = type.GetMethods();
55                Show(myMethodInfo);
56                //获取属性信息
57                PropertyInfo[] myproperties = type.GetProperties();
58                Show(myproperties);
59                //获取事件信息,这个项目没有事件,所以注释掉了,
60                //通过这种办法,还可以获得更多的type相关信息.
61                //EventInfo[] Myevents = type.GetEvents();
62                 //Show(Myevents);
63            }

64            Console.ReadLine();
65        }

66        //显示数组的基本信息
67        public void Show(object[] os)
68        {
69            foreach (object var in os)
70            {
71                Console.WriteLine(var.ToString());
72            }

73            Console.WriteLine("----------------------------------");
74        }

75    }

76}

【注】 通过测试,发现只能获得public类型的信息.

④动态创建对象实例【经典】
是实现抽象工厂的基础,也是实现抽象工厂的核心技术,通过它,可以动态创建一个你想要的对象.如下面的例子是演示如何动态创建ChineseName或EnglishName的实例

 
 1 using  System;
 2 using  System.Reflection;
 3 namespace  TestReflection
 4 {
 5    class AXzhz_sReflectionExample
 6    {
 7        public static void Main()
 8        {
 9            IName name=AbstractFactory.GetName();
10            name.ShowName();
11        }

12    }

13
14    public class AbstractFactory
15    {
16        public static IName GetName()
17        {
18            //s的值以后从Web.config动态获取
19            //把s赋值为:TestReflection.EnglishName,将显示英文名
20            string s = "TestReflection.ChineseName";
21            IName name = (IName)Assembly.Load("TestReflection").CreateInstance(s);
22            return name;
23        }

24    }

25    
26    //声明一个接口,它有一个显示"名字"的功能
27    public interface IName
28    {
29        void ShowName();
30    }

31
32    //实现接口,显示中国名字
33    public class ChineseName : IName
34    {
35        public void ShowName()
36        {
37            Console.WriteLine("我叫AX!");
38            Console.ReadLine();
39        }

40    }

41
42    //实现接口,显示英国名字
43    public class EnglishName:IName
44    {
45        void IName.ShowName()
46        {
47            Console.WriteLine("My name is AXzhz!");
48            Console.ReadLine();
49        }

50    }

51}

⑤获得整个解决方案的所有Assembly(这个有点用)
如果你不太清楚自己的解决方案中都用到了哪些Assembly,可以使用下面的方法,如果再想得到Assembly里的信息, 见③

 1 using  System;
 2 using  System.Reflection;
 3
 4 namespace  TestReflection
 5 {
 6    class ShowAllAssembly
 7    {
 8        public static void Main()
 9        {
10            //获得解决方案的所有Assembly
11            Assembly[] AX = AppDomain.CurrentDomain.GetAssemblies();
12            //遍历显示每个Assembly的名字
13            foreach (object var in AX)
14            {
15                Console.WriteLine("Assembly的名字:"+var.ToString());                
16            }

17            //使用一个已知的Assembly名称,来创建一个Assembly
18            //通过CodeBase属性显示最初指定的程序集的位置
19            Console.WriteLine("最初指定的程序集TestReflection的位置:" + Assembly.Load("TestReflection").CodeBase);
20            Console.ReadLine();
21        }

22    }

23}

24
 

其它的我就不想写了,有兴趣可以看看这个网址,整理的还是比较全.
http://jamedy.vcblog.net/archive/2006/06/12/353849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
两个现实中的例子: 1、B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况。这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时候就会产生一定的“回音”反射,然后把“回音”进行处理就可以显示出内脏的情况了(我不是医生也不是声学专家,不知说得是否准确^_^)。 2、地球内部结构:地球的内部结构大体可以分为三层:地壳、地幔和地核。地壳是固体,地核是液体,地幔则是半液半固的结构(中学地理的内容,大家还记得吧?)。如何在地球表面不用深入地球内部就知道其内部的构造呢?对,向地球发射“地震波”,“地震波”分两种一种是“横波”,另一种是“纵波”。“横波”只能穿透固体,而“纵波”既可穿透固体又可以穿透液体。通过在地面对纵波和横波的反回情况,我们就可以大体断定地球内部的构造了。 大家注意到这两个例子的共同特点,就是从一个对象的外部去了解对象内部的构造,而且都是利用了波的反射功能。在.NET中的反射也可以实现从对象的外部来了解对象(或程序集)内部结构的功能,哪怕你不知道这个对象(或程序集)是个什么东西,另外.NET中的反射还可以运态创建出对象并执行它其中的方法。 反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。 反射的用途: (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。 (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。 (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。 (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。 (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。 反射用到的命名空间: System.Reflection System.Type System.Reflection.Assembly 反射用到的主要类: System.Type 类--通过这个类可以访问任何给定数据类型的信息。 System.Reflection.Assembly类--它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。 System.Type类: System.Type 类对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。 获取给定类型的Type引用有3种常用方式: ●使用 C# typeof 运算符。 Type t = typeof(string); ●使用对象GetType()方法。 string s = "grayworm"; Type t = s.GetType(); ●还可以调用Type类的静态方法GetType()。 Type t = Type.GetType("System.String"); 上面这三类代码都是获取string类型的Type,在取出string类型的Type引用t后,我们就可以通过t来探测string类型的结构了。 string n = "grayworm"; Type t = n.GetType(); foreach (MemberInfo mi in t.GetMembers()) { Console.WriteLine("{0}/t{1}",mi.MemberType,mi.Name); } Type类的属性: Name 数据类型名 FullName 数据类型的完全限定名(包括命名空间名) Namespace 定义数据类型的命名空间名 IsAbstract 指示该类型是否是抽象类型 IsArray 指示该类型是否是数组 IsClass 指示该类型是否是类 IsEnum 指示该类型是否是枚举 IsInterface 指示该类型是否是接口 IsPublic 指示该类型是否是公有的 IsSealed 指示该类型是否是密封类 IsValueType 指示该类型是否是值类型 Type类的方法: GetConstructor(), GetConstructors():返回ConstructorInfo类型,用于取得该类的构造函数的信息 GetEvent(), GetEvents():返回EventInfo类型,用于取得该类的事件的信息 GetField(), GetFields():返回FieldInfo类型,用于取得该类的字段(成员变量)的信息 GetInterface(), GetInterfaces():返回InterfaceInfo类型,用于取得该类实现的接口的信息 GetMember(), GetMembers():返回MemberInfo类型,用于取得该类的所有成员的信息 GetMethod(), GetMethods():返回MethodInfo类型,用于取得该类的方法的信息 GetProperty(), GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息 可以调用这些成员,其方式是调用Type的InvokeMember()方法,或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法。 查看类中的构造方法: NewClassw nc = new NewClassw(); Type t = nc.GetType(); ConstructorInfo[] ci = t.GetConstructors(); //获取类的所有构造函数 foreach (ConstructorInfo c in ci) //遍历每一个构造函数 { ParameterInfo[] ps = c.GetParameters(); //取出每个构造函数的所有参数 foreach (ParameterInfo pi in ps) //遍历并打印所该构造函数的所有参数 { Console.Write(pi.ParameterType.ToString()+" "+pi.Name+","); } Console.WriteLine(); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值