C#反射

什么是反射?

反射提供了封装程序集、模块和类型的对象。

您可以使用反射动态地创建类型的实例( ),将类型绑定到现有对象(这个不会),或从现有对象中获取类型(②③ )。然后,可以调用类型的方法或访问其字段和属性。

最最简单的反射:如下

using System;

using System.Reflection;

namespace TestReflection

{

    class Program

    {

        static void Main(string[] args)

        {

            //创建两个对象【objectObjetct好像没有区别啊??连提示都一样!

            object A = new AX();

            Object B = new AXzhz();

            //获取对象的类型

            new TestObjectType().TestObjectTypeNow(A, B);           

        }

    }

 

    class AX

    {

    }

 

    class AXzhz

    {

    }

 

    class TestObjectType

    {

        //构造函数的默认修饰为private

        internal void TestObjectTypeNow(object A, object B)

        {

            Type tpA = A.GetType();

            Type tpB = B.GetType();

            Console.WriteLine(tpA.FullName);

            Console.WriteLine(tpB.FullName);

            Console.ReadLine();

        }

    }

}

输出结果:

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的信息.

 

 

using System;

using System.Reflection;

namespace TestReflection

{

    class Program

    {

        public static void Main(string[] args)

        {

            object A = new AX();

            //获取对象所属的Assembly的所有类的基本信息

            new TestObjectType().TestObjectTypeNow(A);

        }

    }

 

    class AX

    {

        internal int kkkkkkkk = 0;

        public int ooooooooo;

        private int property;

 

        public int Property

        {

            get { return property; }

            set { property = value; }

        }

        public void A()

        {

            Console.WriteLine("AX's function!~");

        }

    }

 

    class AXzhz

    {

    }

 

    class TestObjectType

    {

        //构造函数的默认修饰为private

        internal void TestObjectTypeNow(object A)

        {

            Type tpA = A.GetType();

            Assembly assembly = tpA.Assembly;

            Type[] types = assembly.GetTypes();

            foreach (Type type in types)

            {

                Console.WriteLine("【类名】"+type.FullName);

                //获取类型的结构信息

                ConstructorInfo[] myconstructors = type.GetConstructors();

                Show(myconstructors);

                //获取类型的字段信息

                FieldInfo[] myfields = type.GetFields();

                Show(myfields);

                //获取方法信息

                MethodInfo[] myMethodInfo = type.GetMethods();

                Show(myMethodInfo);

                //获取属性信息

                PropertyInfo[] myproperties = type.GetProperties();

                Show(myproperties);

                //获取事件信息,这个项目没有事件,所以注释掉了,

                //通过这种办法,还可以获得更多的type相关信息.

                //EventInfo[] Myevents = type.GetEvents();

                 //Show(Myevents);

            }

            Console.ReadLine();

        }

        //显示数组的基本信息

        public void Show(object[] os)

        {

            foreach (object var in os)

            {

                Console.WriteLine(var.ToString());

            }

            Console.WriteLine("----------------------------------");

        }

    }

}

 

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

 

动态创建对象实例【经典】

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

 

 

   1using System;

using System.Reflection;

namespace TestReflection

{

    class AXzhz_sReflectionExample

    {

        public static void Main()

        {

            IName name=AbstractFactory.GetName();

            name.ShowName();

        }

    }

 

    public class AbstractFactory

    {

        public static IName GetName()

        {

            //s的值以后从Web.config动态获取

            //s赋值为:TestReflection.EnglishName,将显示英文名

            string s = "TestReflection.ChineseName";

            IName name = (IName)Assembly.Load("TestReflection").CreateInstance(s);

            return name;

        }

    }

   

    //声明一个接口,它有一个显示"名字"的功能

    public interface IName

    {

        void ShowName();

    }

 

    //实现接口,显示中国名字

    public class ChineseName : IName

    {

        public void ShowName()

        {

            Console.WriteLine("我叫AX!");

            Console.ReadLine();

        }

    }

 

    //实现接口,显示英国名字

    public class EnglishName:IName

    {

        void IName.ShowName()

        {

            Console.WriteLine("My name is AXzhz!");

            Console.ReadLine();

        }

    }

}

获得整个解决方案的所有Assembly(这个有点用)

如果你不太清楚自己的解决方案中都用到了哪些Assembly,可以使用下面的方法,如果再想得到Assembly里的信息,

 

using System;

using System.Reflection;

 

namespace TestReflection

{

    class ShowAllAssembly

    {

        public static void Main()

        {

            //获得解决方案的所有Assembly

            Assembly[] AX = AppDomain.CurrentDomain.GetAssemblies();

            //遍历显示每个Assembly的名字

            foreach (object var in AX)

            {

                Console.WriteLine("Assembly的名字:"+var.ToString());               

            }

            //使用一个已知的Assembly名称,来创建一个Assembly

            //通过CodeBase属性显示最初指定的程序集的位置

            Console.WriteLine("最初指定的程序集TestReflection的位置:" + Assembly.Load("TestReflection").CodeBase);

            Console.ReadLine();

        }

    }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值