• C#反射


    C#编译后的文件主要由IL代码和元数据组成,元数据为.NET组件提供了丰富的自描述特性,它使得我们可以在代码运行时获知组件中的类型等重要的信息。C#中这是通过一种称作反射(Reflection)的机制来完成的。

    动态类型查询

    首先创建一个简单的类型

    namespace ReflectionClass

    {

        public class MyClass

        {

            #region Property

            private int m_Count = 100;

            public int Count

            {

                get

                {

                    return m_Count;

                }

                set

                {

                    m_Count = value;

                }

            }

            #endregion

     

            #region Method

            public void Print()

            {

                Console.WriteLine("MyClass.Count = {}", Count);

            }

            #endregion

    }

    }

    编译后可以得到“ReflectionClass.dll”文件,接下来实现查询类型的测试程序:

    namespace TestReflection

    {

        public class App

        {

            static void Main(string[] args)

            {

                Type type = typeof(MyClass); //获取MyClass的类型信息

                Console.WriteLine("The Type Name : {0}", type.Name); //获取类型的名字

     

                FieldInfo[] fieldArray = type.GetFields(); //获取所有的公有域

                Console.Write("The {0} Fields : ", fieldArray.Length);

                foreach (FieldInfo field in fieldArray)

                {

                    Console.Write(field.Name + " ");

                }

                Console.WriteLine();

                PropertyInfo[] propertyArray = type.GetProperties(); //获取所有的公有属性

                Console.Write("The {0} Properties : ", propertyArray.Length);

                foreach (PropertyInfo property in propertyArray)

                {

                    Console.Write(property.Name + " ");

                }

                Console.WriteLine();

                MethodInfo[] methodArray = type.GetMethods(); //获取所有的公有方法

                Console.Write("The {0} Methods : ", methodArray.Length);

                foreach (MethodInfo method in methodArray)

                {

                    Console.Write(method.Name + " ");

                }

            }

        }

    }

    编译后执行,可以得到以下输出:

    The Type Name : MyClass

    The 0 Fields :

    The 1 Properties : Count

    The 7 Methods : get_Count set_Count Print ToString Equals GetHashCode GetType

    在上面的例子中,首先通过 typeof(MyClass)获得MyClass类的类型信息,当然也可以通过创建对象实例,然后调用对象实例的GetType方法来获得(每个类都从 object根类中继承获得此方法)。在拥有了类型信息(变量type)后,便可以获得其类型的名字、该类型含有的公有域、公有属性、公有方法。注意: 这里C#的反射机制只允许获取类型的公有信息,这符合面向对象的封装原则。其中4个方法(GetHashCodeEqualsToStringGetType)都是继承自object类的公有方法,而方法get_Count set_Count则是实现Count属性的副产物。实际上,System.Type类各种各样的成员使得我们能够获得几乎所有与类型相关的公有信息。在System.Reflection命名空间下的各个类都可以获得各个编程元素较详细的信息,如方法的参数与返回值、域的类型、枚举的各个值等

    动态创建与调用

    实际上反射远不止动态地获知组件的类型信息,它还能在获得类型信息的基础上,在代码运行时进行类型的动态创建与方法的动态调用。

    namespace TestReflection2

    {

        public class App

        {

            static void Main(string[] args)

            {

                Assembly assemlby = Assembly.LoadFrom("ReflectionClass.dll"); //装载组件

                foreach (var type in assemlby.GetTypes())

                {

                    if (type.IsClass && !type.IsAbstract)

                    {

                        MethodInfo[] methodArray = type.GetMethods(); //获得类型的公有方法

                        object obj = Activator.CreateInstance(type); //创建实例(无参构造器)

                        foreach (var method in methodArray)

                        {

                            if (!method.IsAbstract && !method.IsStatic && method.GetParameters().Length == 0)

                            {

                                object ret = method.Invoke(obj, null); //调用实例方法

                                Console.WriteLine("{0}'s Return : {1}", method.Name, ret);

                            }

                        }

                    }

                }

            }

        }

    }

    编译后执行,可以得到以下输出:

    get_Count's Return : 100

    MyClass.Count = 100

    Print's Return :

    ToString's Return : ReflectionClass.MyClass

    GetHashCode's Return : 62476613

    GetType's Return : ReflectionClass.MyClass

    在上面的例子中给出了被动态调用的方法名字和返回值。其中第二行输出的“MyClass.Count = 100”,它是动态调用方法MyClass.Print()的输出。需要指出的是调用的是类型的公有无参数实例方法。给出组件的名字,应用Assembly.LoadFrom,我们便可以动态地装载组件。 Activator.CreateInstance()允许动态地创建类型(这里只通过无参数的构造器来创建),实际上用它创建出来的类型和用MyClass obj = new MyClass()创建出来的类型一样。进而,还可以在查询到的成员的基础上,对它们进行动态调用。

    另外,还可以用“Assembly.CreateInstance()创建实例,从本质上讲,Assembly.CreateInstance()”就是调用的“Activator.CreateInstance()”。
  • 相关阅读:
    gorm 创建数据时字段跟结构体不一致
    查看端口信息
    Mysql 新建用户 并指定能访问的数据库权限
    网页端实现快速播放(有些网页不让快进.....的解决办法)
    Mybatis Map保存到数据库,Mybatis Map动态同步表,Mybatis Map Foreach插入数据库
    Java 获取Exception详细信息,Java获取异常详细内容
    weblogic禁用IIOP协议,weblogic CVE-2020-2551漏洞修复
    IntelliJ IDEA安装配置,IntelliJ IDEA配置Maven,IntelliJ IDEA设置热部署
    Java URL链接动态添加参数,Java URL链接删除参数,UrlUtils链接参数工具类
    Oracle weblogic隐藏console,weblogic修改控制台console入口
  • 原文地址:https://www.cnblogs.com/jsll/p/13996660.html
Copyright © 2020-2023  润新知