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

原文地址为: C#反射Reflection学习随笔(完结篇)_AX

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

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

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

155bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

161408c5260b2f05e450dee929db9be5f7.jpe
171408c5260b2f05e450dee929db9be5f7.jpe    class AX
18715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
195bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

201408c5260b2f05e450dee929db9be5f7.jpe
211408c5260b2f05e450dee929db9be5f7.jpe    class AXzhz
22715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
235bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

241408c5260b2f05e450dee929db9be5f7.jpe
251408c5260b2f05e450dee929db9be5f7.jpe    class TestObjectType
26715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
271408c5260b2f05e450dee929db9be5f7.jpe        //构造函数的默认修饰为private
281408c5260b2f05e450dee929db9be5f7.jpe        internal void TestObjectTypeNow(object A, object B)
29715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
301408c5260b2f05e450dee929db9be5f7.jpe            Type tpA = A.GetType();
311408c5260b2f05e450dee929db9be5f7.jpe            Type tpB = B.GetType();
321408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine(tpA.FullName);
331408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine(tpB.FullName);
341408c5260b2f05e450dee929db9be5f7.jpe            Console.ReadLine();
355bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

365bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

37f466905a3bcb5dcef110eab799825254.jpe}

输出结果:
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 731655954c7be9d8835ece551b5385f8.jpe using  System;
 2 731655954c7be9d8835ece551b5385f8.jpe using  System.Reflection;
 3 731655954c7be9d8835ece551b5385f8.jpe namespace  TestReflection
 4 24a924a57ba6b3f2b51fc9edb7ea4186.jpe9310e85a14af99de4811ff4c77f1f911.jpe 222530190136c9c4cfd237cc0d5cff99.jpe {
 51408c5260b2f05e450dee929db9be5f7.jpe    class Program
 6715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
 71408c5260b2f05e450dee929db9be5f7.jpe        public static void Main(string[] args)
 8715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
 91408c5260b2f05e450dee929db9be5f7.jpe            object A = new AX();
101408c5260b2f05e450dee929db9be5f7.jpe            //获取对象所属的Assembly的所有类的基本信息
111408c5260b2f05e450dee929db9be5f7.jpe            new TestObjectType().TestObjectTypeNow(A);
125bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

135bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

141408c5260b2f05e450dee929db9be5f7.jpe
151408c5260b2f05e450dee929db9be5f7.jpe    class AX
16715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
171408c5260b2f05e450dee929db9be5f7.jpe        internal int kkkkkkkk = 0;
181408c5260b2f05e450dee929db9be5f7.jpe        public int ooooooooo;
191408c5260b2f05e450dee929db9be5f7.jpe        private int property;
201408c5260b2f05e450dee929db9be5f7.jpe
211408c5260b2f05e450dee929db9be5f7.jpe        public int Property
22715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
23715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe            get 222530190136c9c4cfd237cc0d5cff99.jpereturn property; }
24715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe            set 222530190136c9c4cfd237cc0d5cff99.jpe{ property = value; }
255bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

261408c5260b2f05e450dee929db9be5f7.jpe        public void A()
27715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
281408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine("AX's function!~");
295bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

305bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

311408c5260b2f05e450dee929db9be5f7.jpe
321408c5260b2f05e450dee929db9be5f7.jpe    class AXzhz
33715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
345bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

351408c5260b2f05e450dee929db9be5f7.jpe
361408c5260b2f05e450dee929db9be5f7.jpe    class TestObjectType
37715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
381408c5260b2f05e450dee929db9be5f7.jpe        //构造函数的默认修饰为private
391408c5260b2f05e450dee929db9be5f7.jpe        internal void TestObjectTypeNow(object A)
40715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
411408c5260b2f05e450dee929db9be5f7.jpe            Type tpA = A.GetType();
421408c5260b2f05e450dee929db9be5f7.jpe            Assembly assembly = tpA.Assembly;
431408c5260b2f05e450dee929db9be5f7.jpe            Type[] types = assembly.GetTypes();
441408c5260b2f05e450dee929db9be5f7.jpe            foreach (Type type in types)
45715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe            222530190136c9c4cfd237cc0d5cff99.jpe{
461408c5260b2f05e450dee929db9be5f7.jpe                Console.WriteLine("【类名】"+type.FullName);
471408c5260b2f05e450dee929db9be5f7.jpe                //获取类型的结构信息
481408c5260b2f05e450dee929db9be5f7.jpe                ConstructorInfo[] myconstructors = type.GetConstructors();
491408c5260b2f05e450dee929db9be5f7.jpe                Show(myconstructors);
501408c5260b2f05e450dee929db9be5f7.jpe                //获取类型的字段信息
511408c5260b2f05e450dee929db9be5f7.jpe                FieldInfo[] myfields = type.GetFields();
521408c5260b2f05e450dee929db9be5f7.jpe                Show(myfields);
531408c5260b2f05e450dee929db9be5f7.jpe                //获取方法信息
541408c5260b2f05e450dee929db9be5f7.jpe                MethodInfo[] myMethodInfo = type.GetMethods();
551408c5260b2f05e450dee929db9be5f7.jpe                Show(myMethodInfo);
561408c5260b2f05e450dee929db9be5f7.jpe                //获取属性信息
571408c5260b2f05e450dee929db9be5f7.jpe                PropertyInfo[] myproperties = type.GetProperties();
581408c5260b2f05e450dee929db9be5f7.jpe                Show(myproperties);
591408c5260b2f05e450dee929db9be5f7.jpe                //获取事件信息,这个项目没有事件,所以注释掉了,
601408c5260b2f05e450dee929db9be5f7.jpe                //通过这种办法,还可以获得更多的type相关信息.
611408c5260b2f05e450dee929db9be5f7.jpe                //EventInfo[] Myevents = type.GetEvents();
621408c5260b2f05e450dee929db9be5f7.jpe                 //Show(Myevents);
635bcb1807ee3e00d2b3c225f0b3f5c751.jpe            }

641408c5260b2f05e450dee929db9be5f7.jpe            Console.ReadLine();
655bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

661408c5260b2f05e450dee929db9be5f7.jpe        //显示数组的基本信息
671408c5260b2f05e450dee929db9be5f7.jpe        public void Show(object[] os)
68715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
691408c5260b2f05e450dee929db9be5f7.jpe            foreach (object var in os)
70715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe            222530190136c9c4cfd237cc0d5cff99.jpe{
711408c5260b2f05e450dee929db9be5f7.jpe                Console.WriteLine(var.ToString());
725bcb1807ee3e00d2b3c225f0b3f5c751.jpe            }

731408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine("----------------------------------");
745bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

755bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

76f466905a3bcb5dcef110eab799825254.jpe}

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

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

 
 1 731655954c7be9d8835ece551b5385f8.jpe using  System;
 2 731655954c7be9d8835ece551b5385f8.jpe using  System.Reflection;
 3 731655954c7be9d8835ece551b5385f8.jpe namespace  TestReflection
 4 24a924a57ba6b3f2b51fc9edb7ea4186.jpe9310e85a14af99de4811ff4c77f1f911.jpe 222530190136c9c4cfd237cc0d5cff99.jpe {
 51408c5260b2f05e450dee929db9be5f7.jpe    class AXzhz_sReflectionExample
 6715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
 71408c5260b2f05e450dee929db9be5f7.jpe        public static void Main()
 8715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
 91408c5260b2f05e450dee929db9be5f7.jpe            IName name=AbstractFactory.GetName();
101408c5260b2f05e450dee929db9be5f7.jpe            name.ShowName();
115bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

125bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

131408c5260b2f05e450dee929db9be5f7.jpe
141408c5260b2f05e450dee929db9be5f7.jpe    public class AbstractFactory
15715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
161408c5260b2f05e450dee929db9be5f7.jpe        public static IName GetName()
17715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
181408c5260b2f05e450dee929db9be5f7.jpe            //s的值以后从Web.config动态获取
191408c5260b2f05e450dee929db9be5f7.jpe            //把s赋值为:TestReflection.EnglishName,将显示英文名
201408c5260b2f05e450dee929db9be5f7.jpe            string s = "TestReflection.ChineseName";
211408c5260b2f05e450dee929db9be5f7.jpe            IName name = (IName)Assembly.Load("TestReflection").CreateInstance(s);
221408c5260b2f05e450dee929db9be5f7.jpe            return name;
235bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

245bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

251408c5260b2f05e450dee929db9be5f7.jpe    
261408c5260b2f05e450dee929db9be5f7.jpe    //声明一个接口,它有一个显示"名字"的功能
271408c5260b2f05e450dee929db9be5f7.jpe    public interface IName
28715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
291408c5260b2f05e450dee929db9be5f7.jpe        void ShowName();
305bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

311408c5260b2f05e450dee929db9be5f7.jpe
321408c5260b2f05e450dee929db9be5f7.jpe    //实现接口,显示中国名字
331408c5260b2f05e450dee929db9be5f7.jpe    public class ChineseName : IName
34715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
351408c5260b2f05e450dee929db9be5f7.jpe        public void ShowName()
36715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
371408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine("我叫AX!");
381408c5260b2f05e450dee929db9be5f7.jpe            Console.ReadLine();
395bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

405bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

411408c5260b2f05e450dee929db9be5f7.jpe
421408c5260b2f05e450dee929db9be5f7.jpe    //实现接口,显示英国名字
431408c5260b2f05e450dee929db9be5f7.jpe    public class EnglishName:IName
44715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
451408c5260b2f05e450dee929db9be5f7.jpe        void IName.ShowName()
46715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
471408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine("My name is AXzhz!");
481408c5260b2f05e450dee929db9be5f7.jpe            Console.ReadLine();
495bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

505bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

51f466905a3bcb5dcef110eab799825254.jpe}

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

 1 731655954c7be9d8835ece551b5385f8.jpe using  System;
 2 731655954c7be9d8835ece551b5385f8.jpe using  System.Reflection;
 3 731655954c7be9d8835ece551b5385f8.jpe
 4 731655954c7be9d8835ece551b5385f8.jpe namespace  TestReflection
 5 24a924a57ba6b3f2b51fc9edb7ea4186.jpe9310e85a14af99de4811ff4c77f1f911.jpe 222530190136c9c4cfd237cc0d5cff99.jpe {
 61408c5260b2f05e450dee929db9be5f7.jpe    class ShowAllAssembly
 7715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe    222530190136c9c4cfd237cc0d5cff99.jpe{
 81408c5260b2f05e450dee929db9be5f7.jpe        public static void Main()
 9715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe        222530190136c9c4cfd237cc0d5cff99.jpe{
101408c5260b2f05e450dee929db9be5f7.jpe            //获得解决方案的所有Assembly
111408c5260b2f05e450dee929db9be5f7.jpe            Assembly[] AX = AppDomain.CurrentDomain.GetAssemblies();
121408c5260b2f05e450dee929db9be5f7.jpe            //遍历显示每个Assembly的名字
131408c5260b2f05e450dee929db9be5f7.jpe            foreach (object var in AX)
14715f2d05503b99d41f3b6ba2cdccc84d.jpee083dfde5a91f50979fe8979b4012b9d.jpe            222530190136c9c4cfd237cc0d5cff99.jpe{
151408c5260b2f05e450dee929db9be5f7.jpe                Console.WriteLine("Assembly的名字:"+var.ToString());                
165bcb1807ee3e00d2b3c225f0b3f5c751.jpe            }

171408c5260b2f05e450dee929db9be5f7.jpe            //使用一个已知的Assembly名称,来创建一个Assembly
181408c5260b2f05e450dee929db9be5f7.jpe            //通过CodeBase属性显示最初指定的程序集的位置
191408c5260b2f05e450dee929db9be5f7.jpe            Console.WriteLine("最初指定的程序集TestReflection的位置:" + Assembly.Load("TestReflection").CodeBase);
201408c5260b2f05e450dee929db9be5f7.jpe            Console.ReadLine();
215bcb1807ee3e00d2b3c225f0b3f5c751.jpe        }

225bcb1807ee3e00d2b3c225f0b3f5c751.jpe    }

23f466905a3bcb5dcef110eab799825254.jpe}

24 731655954c7be9d8835ece551b5385f8.jpe
 

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

惟一的遗憾:将类型绑定到现有对象 不知道怎么弄

转载请注明本文地址: C#反射Reflection学习随笔(完结篇)_AX

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/81409760