C#反射 Reflection学习随笔(完结篇)_AX

  1. 云栖社区>
  2. 博客>
  3. 正文

C#反射 Reflection学习随笔(完结篇)_AX

老朱教授 2017-08-27 18:40:00 浏览814
展开阅读全文


①什么是反射?
反射提供了封装程序集、模块和类型的对象。
您可以使用反射动态地创建类型的实例(见④ ),将类型绑定到现有对象(这个不会),或从现有对象中获取类型(见②③ )。然后,可以调用类型的方法或访问其字段和属性。
最最简单的反射:如下

 1None.gifusing System;
 2None.gifusing System.Reflection;
 3None.gifnamespace TestReflection
 4ExpandedBlockStart.gif{
 5InBlock.gif    class Program
 6ExpandedSubBlockStart.gif    {
 7InBlock.gif        static void Main(string[] args)
 8ExpandedSubBlockStart.gif        {
 9InBlock.gif            //创建两个对象【object和Objetct好像没有区别啊??连提示都一样!】
10InBlock.gif            object A = new AX();
11InBlock.gif            Object B = new AXzhz();
12InBlock.gif            //获取对象的类型
13InBlock.gif            new TestObjectType().TestObjectTypeNow(A, B);            
14ExpandedSubBlockEnd.gif        }

15ExpandedSubBlockEnd.gif    }

16InBlock.gif
17InBlock.gif    class AX
18ExpandedSubBlockStart.gif    {
19ExpandedSubBlockEnd.gif    }

20InBlock.gif
21InBlock.gif    class AXzhz
22ExpandedSubBlockStart.gif    {
23ExpandedSubBlockEnd.gif    }

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

36ExpandedSubBlockEnd.gif    }

37ExpandedBlockEnd.gif}


输出结果:
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的信息.

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

13ExpandedSubBlockEnd.gif    }

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

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

30ExpandedSubBlockEnd.gif    }

31InBlock.gif
32InBlock.gif    class AXzhz
33ExpandedSubBlockStart.gif    {
34ExpandedSubBlockEnd.gif    }

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

64InBlock.gif            Console.ReadLine();
65ExpandedSubBlockEnd.gif        }

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

73InBlock.gif            Console.WriteLine("----------------------------------");
74ExpandedSubBlockEnd.gif        }

75ExpandedSubBlockEnd.gif    }

76ExpandedBlockEnd.gif}


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

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

 1None.gifusing System;
 2None.gifusing System.Reflection;
 3None.gifnamespace TestReflection
 4ExpandedBlockStart.gif{
 5InBlock.gif    class AXzhz_sReflectionExample
 6ExpandedSubBlockStart.gif    {
 7InBlock.gif        public static void Main()
 8ExpandedSubBlockStart.gif        {
 9InBlock.gif            IName name=AbstractFactory.GetName();
10InBlock.gif            name.ShowName();
11ExpandedSubBlockEnd.gif        }

12ExpandedSubBlockEnd.gif    }

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

24ExpandedSubBlockEnd.gif    }

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

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

40ExpandedSubBlockEnd.gif    }

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

50ExpandedSubBlockEnd.gif    }

51ExpandedBlockEnd.gif}


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

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

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

22ExpandedSubBlockEnd.gif    }

23ExpandedBlockEnd.gif}

24None.gif



本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/05/15/1736244.html,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
老朱教授
+ 关注