C#之入门总结_反射_15

来源:互联网 发布:怎么查看淘宝会员等级 编辑:程序博客网 时间:2024/06/13 05:23
Reflection,中文翻译为反射。
        这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:

        Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。


反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

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

优点:

    1、反射提高了程序的灵活性和扩展性。
    2、降低耦合性,提高自适应能力。
    3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

    1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
    2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射(Reflection)有下列用途:

    它允许在运行时查看特性(attribute)信息。
    它允许审查集合中的各种类型,以及实例化这些类型。
    它允许延迟绑定的方法和属性(property)。
    它允许在运行时创建新类型,然后使用这些类型执行一些任务。

反射用到的命名空间:
   System.Reflection
   System.Type
   System.Reflection.Assembly

   (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。    
   (2)使用Type这个类可以访问任何给定数据类型的信息。
   (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
   (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
   (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
   (6)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。

System.Type类:
   System.Type 类对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。
   获取给定类型的Type引用有3种常用方式:
   ●使用 C# typeof 运算符。已知类型
       Type t = typeof(string);
   ●使用对象GetType()方法。 已知对象
       string s = "grayworm";
       Type t = s.GetType();
   ●还可以调用Type类的静态方法GetType()。已知类名
       Type t = Type.GetType("System.String");

//获取类的描述对象
Type t = obj.GetType();
//取得字段描述对象
FieldInfo fi = t.GetField("name");
//获取或设置字段值
fi.SetValue(obj, "k001");
fi.GetValue(obj);

一般在C#中以属性替代字段
//获取类的描述对象
Type t = obj.GetType();
//取得属性描述对象
PropertyInfo pi1 = t.GetProperty("Name");
//获取或设置属性值
pi1.SetValue(obj, "k001",null);
pi1.GetValue(obj,null);

//获取类的描述对象
Type t = obj.GetType();
//取得方法描述对象
MethodInfo mi = t.GetMethod("show");
//调用方法
mi.Invoke(obj, "实参1",实参2(int));
参数可以换成数组

           //Type的引入
            Type type = typeof(int);            
            Console.WriteLine(type.Assembly);
            Console.WriteLine(type.Attributes);
            Console.WriteLine(type.IsAbstract);
            Console.WriteLine(type.IsClass);
            Console.WriteLine(type.IsArray);
            Console.WriteLine(type.Namespace);
            Console.WriteLine(type.Name);
            Console.WriteLine(type.FullName);
            //得到基类
            Console.WriteLine(type.BaseType);
            Console.WriteLine("-----------反射的开始-----------");          
            Type t = Type.GetType("反射1.Student");
            Console.WriteLine(t.Name);
            Console.WriteLine("-------------------");
            Console.WriteLine(t.BaseType);
            Assembly assem = Assembly.GetAssembly(t);
            //程序集的全称
            Console.WriteLine(assem.FullName);
            //程序集的程序入口  
            Console.WriteLine(assem.EntryPoint);
            //Console.WriteLine(assem.);
            //根据命名空间和类名  实例化一个对象
            object studentObj = assem.CreateInstance("反射1.Student");
            //根据对象获取类中的信息 字段 属性 方法  
            Type studentType = studentObj.GetType();
            //获取类中的私有字段
            FieldInfo[] fieldInfoArr = studentType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            Console.WriteLine(fieldInfoArr.Length +"++");
            foreach (var item in fieldInfoArr)
            {
                Console.WriteLine(item);
            }
            //获取类中的属性
            PropertyInfo[] propInfoArr = studentType.GetProperties();
            foreach (var item in propInfoArr)
            {
                Console.WriteLine(item);
            }
            //获取到类中的方法  包含父类中的虚方法
            MethodInfo[] methodinfoArr = studentType.GetMethods();
            foreach (var item in methodinfoArr)
            {
                Console.WriteLine(item);
            }
            PropertyInfo propName = studentType.GetProperty("Name");
            propName.SetValue(studentObj,"Jack");
            PropertyInfo propAge = studentType.GetProperty("Age");
            propAge.SetValue(studentObj,20);
            PropertyInfo propGender = studentType.GetProperty("Gender");
            propGender.SetValue(studentObj, '男');
            MethodInfo methodShow = studentType.GetMethod("ShowInfoMation");
            methodShow.Invoke( studentObj,null);


class Student
    {
        private string name;
        private int age;
        private char gender;
        public string Name
        {
            get
            {
                return name;
            }

            set
            {
                name = value;
            }
        }

        public int Age
        {
            get
            {
                return age;
            }

            set
            {
                age = value;
            }
        }

        public char Gender
        {
            get
            {
                return gender;
            }

            set
            {
                gender = value;
            }
        }

        public Student()
        {

        }
        public Student(string name, int age, char gender)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
        }

        public void ShowInfoMation()
        {
            Console.WriteLine("姓名:{0}年龄:{1}性别:{2}",Name,Age,Gender);
        }

    }