• c#反射学习小结


         反射是一种机制,通过这种机制我们可以知道一个未知类型的类型信息.比如,有一个对象a,这个对象不是我们定义的,也许是通过网络捕捉到的,也许是使用泛型定义的,但我们想知道这个对象的类型信息,想知道这个对象有哪些方法或者属性什么的.甚至我们想进一步调用这个对象的方法.关键是现在我们只知道它是一个对象,不知道它的类型,自然不会知道它有哪些方法等信息.这时我们该怎么办?反射机制就是解决这么一个问题的.通过反射机制我们可以知道未知类型对象的类型信息.
      再比如,我们有一个dll文件,我们想调用里面的类.现在假设这个dll文件的类的定义,数量等不是固定的,是经常变化的.也许某一天你要在这个dll里面增加一个类定义.也许你觉得这没什么问题,现在关键是我们在另一个程序集里面要调用这个dll,这是我们的程序必须能够适应这个dll的变化,也就是说即使改变了dll文件的定义也不需要改变我们的程序集.这时候我们就会使用一个未知dll.我们该怎么办?同样,反射机制帮助了我们,我们可以通过反射来实现.

    下面我举一个例子说明:

    首先我新建一个控制台应用程序,然后添加一个类库Model,在类库中添加一个类People.cs如下:

    namespace Model
    {
        public class People
        {
            public string name { get; set; }
            public string sex { get; set; }
            public int age { get; set; }
    
            public string GetName()
            {
    
                return "我的名字是" + name;
            }
    
            public string Display()
            {
                return "我的名字是:" + name + "\n我的性别是:" + sex + "\n我的年龄:" + age+"\n";
            
            }
            public People(string name,string sex,int age)
            {
                this.name = name;
                this.sex = sex;
                this.age = age;
            
            
            }
    
    
        }
    }
    

    然后在main函数中些如下代码:

    static void Main(string[] args)
            {
                var asssembly = Assembly.Load("Model");//加载程序集
                Console.WriteLine("程序集名称:{0}", asssembly.FullName);
                   Console.WriteLine();
    
                Type people = asssembly.GetType("Model.People");//获取类型信息,这里要写完整的名称
                Object[] PeopleParms = new object[] {"袁安云","男",22}; //构造器参数,这就要求重载构造函数,如果我想这样写me.name="袁安云",多方便啊,
    //不过这样的话,需要强制类型转换,如:var you=(Model.People)me,然后you.name="袁安云";
                Object me = Activator.CreateInstance(people,PeopleParms);//根据类型创建对象
                MethodInfo method = people.GetMethod("Display");//获取方法的信息
                Console.WriteLine(method.Invoke(me, null));//调用方法,第二个参数为方法的参数,是一个object类型数组,不需要参数时设为null
    
                        Console.ReadKey();
                
    
            }
    

    运行结果:

    说明:

    在VS.Net中,有很多种方法动态调用对象的构造函数。一是通过Activator类的CreateInstance()方法。这个方法我们在Remoting中也用过。它实际上是在本地或从远程创建对象类型,或获取对现有远程对象的引用。它的方法签名是:public static object CreateInstance(Type);(还有其他重载方法)注意它的返回值为object,MSDN对返回值的描述是:对新创建对象的引用。
    二是通过Assembly类的方法CreateInstance()。方法名和前一样,不过它不是静态方法。Assembly是在System.Reflection命名空间中。方法签名:public object CreateInstance(Type);(同样还有其他重载方法)返回值仍然是object,MSDN对返回值的描述是:表示该类型的 Object 的实例,其区域性、参数、联编程序和激活属性设置为空引用(Visual Basic 中为 Nothing),并且 BindingFlags 设置为 Public 或 Instance,或者设置为空引用 (Nothing)(如果没有找到 typeName)。

    当然还有其他方法,例如通过MethodInfo获得方法信息后,根据IsConstructor属性,判断是否构造函数,再根据GetParamters()方法获得参数,最后通过Invoke()方法来调用,等等……。大家可以参考MSDN。

    问题:

    以上调用方法Display是这样实现的:

                MethodInfo method = people.GetMethod("Display");//获取方法的信息
                Console.WriteLine(method.Invoke(me, null));//调用方法,第二个参数为方法的参数,是一个object类型数组,不需要参数时设为null

    如果我想这样写me.Display(),该如果实现呢?采用强制类型转换即可:

      var you = (Model.People) me;
      Console.WriteLine(you.Display());


     

    仅此而已
  • 相关阅读:
    网上购物商城管理系统-毕业设计
    中国购物管理系统-毕业设计
    网上购物管理系统-毕业设计
    网上商城管理系统-课程设计
    公益捐赠管理系统-毕业设计
    校园图书捐赠管理系统-毕业设计
    电子商务商城管理系统-毕业设计
    超市会员管理系统-毕业设计
    天猫商城管理系统-毕业设计
    高校校园设备管理系统-毕业设计
  • 原文地址:https://www.cnblogs.com/yuananyun/p/1860453.html
Copyright © 2020-2023  润新知