zoukankan      html  css  js  c++  java
  • c#之反射总结

     1、了解什么事程序集

     

    2、加载程序集

    首先要加载需要加载的程序集,然后找到指定的类型,进而往下进行动态加载。

    要加载的程序集中的内容:

     1     public class Class1:Person
     2     {
     3         private string name;
     4         private int age;
     5         private void SayHi()
     6         {
     7             Console.WriteLine("hello shit!");
     8         }
     9     }
    10 
    11     public delegate void VoidDel();
    12 
    13     public class MyClass
    14     {
    15         private void MySayHi()
    16         {
    17             Console.WriteLine("my hello shit!");
    18         }
    19     }
    20     internal enum Hopppy
    21     {
    22         游泳,
    23         篮球,
    24         足球
    25     }
    26 
    27     public class Person
    28     {
    29         public string Name { set; get; }
    30         public int Age { set; get; }
    31 
    32         public void Shit()
    33         {
    34             Console.WriteLine("I love you,shit!");
    35         }
    36     }
    37 
    38     public class Chinses : Person, IXiFuable
    39     {
    40         public string Hoppy { set; get; }
    41 
    42         public void XiFu()
    43         {
    44             Console.WriteLine("中国人又自我修复的功能!");
    45         }
    46     }
    47 
    48     interface IXiFuable
    49     {
    50         void XiFu();
    51     }
    52 
    53     public abstract class MyAbsClass
    54     {
    55     }
    程序集中的内容

    加载程序集:

    1             //反射:命名空间(System.Reflection;);用于指向特定的程序集,返回程序集的元数据
    2 
    3             //加载程序集(Assembly:程序集)
    4             Assembly asm = Assembly.LoadFile(@"C:练习委托和多线程基础练习clRefletorinDebugclRefletor.dll");

    获得程序集下面的所有类型(包括私有的和internal)

    1 Type[] types = asm.GetTypes();
    2             foreach (var item in types)
    3             {
    4                 //(包括私有和internal)类型名称 命名空间            命名空间.类型名称
    5                 Console.WriteLine("Name:" + item.Name + ";namespace:" + item.Namespace + ";FullName:" + item.FullName);
    6             }

     获得程序集下面所有的“公有”的类型

    Type[] ExportedTypes= asm.GetExportedTypes();

    3、获得指定类型的三种方法(反射的核心)

     含有一个测试的Person类:

    1     public class Person
    2     {
    3         public string Name { set; get; }
    4         public int Age { set; get; }
    5     }

    获得Type的三种方法

     1             //1、通过 实例对象的GetType()方法
     2             Person person = new Person();
     3             Type type1 = person.GetType();
     4 
     5             //2、通过 typeof(对象的类型名(例如:Person(就是类Person)))
     6             Type type2 = typeof(Person);
     7 
     8             //3、通过 程序集Assembly
     9             Assembly asm = Assembly.LoadFile("扩展程序集的地址");
    10             Type type3 = asm.GetType("Person"); 

    4、Type类型的动态调用成员

    得到类型之后,就能找到他下面的所有的属性、字段、方法、接口、事件等

    获得Type下面的所有的”公有“属性

                Type asmType = asm.GetType("clRefletor.Class1", true, false);//第一个是“类型的全名”,第二个参数:找不到时触发异常,第三个参数:寻找的时候是否忽略大小写
                
                PropertyInfo[] propInfos = asmType.GetProperties();
                foreach (var item in propInfos)
                {
                    Console.WriteLine("属性Name:" + item.Name + "属性的类型名称:" + item.PropertyType.Name + ";是否可读:" + item.CanRead + ";是否可写:" + item.CanWrite);
                }

     获得Type下面的所有的“公有”方法

    1             //这个时候 会将所有的方法全部都 取出来,包括 继承父类的方法和  属性执行的两个方法(非private和非protected的方法)
    2             MethodInfo[] asmMenthods = asmType.GetMethods();
    3             foreach (var asmMethod in asmMenthods)
    4             {
    5                 Console.WriteLine(asmMethod.Name + ";声明此方法的类:" + asmMethod.DeclaringType.Name + asmMethod);
    6             }

    上面 动态获得的都是“公有”,要想获得私有的要进行设置

    获得私有的方法:

    1             Type typePerson=typeof(Person);
    2             //获得非私有的 方法( BindingFlags.NonPublic | BindingFlags.Instance主要靠这个枚举)
    3             MethodInfo perMethod= typePerson.GetMethod("SayHi", BindingFlags.NonPublic | BindingFlags.Instance);
    4             object obj = Activator.CreateInstance(typePerson);
    5             perMethod.Invoke(obj, null);//方法没有参数,所以传值 为null
    6             //获得所有的 非公有的方法
    7             MethodInfo[] perMothods = typePerson.GetMethods(BindingFlags.NonPublic|BindingFlags.Instance);

    动态获得其他内容就不在演示,基本都一样。

     5、通过Type创建对应的实例对象,进而通过反射设置其属性的值、取到属性的值、调用对应的方法等

     通过Type类型创建实例对象

    1             //获得当前类的实例,,就可以 赋值 此类的属性 和取得属性的值,还可以执行此类中的 方法(都是共有的,因为私有的取不到)
    2             object classTarget = Activator.CreateInstance(asmType);

    通过实例对象对属性赋值

    1             //为属性赋值
    2             var pror = asmType.GetProperty("Name");
    3             pror.SetValue(classTarget, "shit",null);//第三个参数 只有索引才填
    4             Console.WriteLine(pror.GetValue(classTarget,null));

    通过实例对象调用指定的方法

    1             //执行 通过反射得到的方法
    2             MethodInfo method = asmType.GetMethod("Shit");
    3             method.Invoke(classTarget, null);//第一个参数:如果方法是静态方法,就传递一个null就可以了,如果是实例方法,就是调用此方法的 对象(这里是Class1);第二个参数:object数组:传到方法里面的 参数(参数的个数不同,可以识别 方法的重载)

     6、Type类型常用的验证方法和需要注意点

    首先获得下面需要用到的类型

    1             Assembly asm = Assembly.LoadFile(@"C:练习委托和多线程基础练习clRefletorinDebugclRefletor.dll");
    2             Type typePerson = asm.GetType("clRefletor.Person");
    3             Type typeChinese = asm.GetType("clRefletor.Chinses");
    4             Type typeIXiufuable = asm.GetType("clRefletor.IXiFuable");
    5             Type typeAbsClass = asm.GetType("clRefletor.MyAbsClass");

    1》IsAssignableFrom (Type)

     判断方法里的类型是否可以赋值给当前类型。(注意:接口和父类都可以

    1             bool b1 = typePerson.IsAssignableFrom(typeChinese);//True
    2             bool b2 = typeIXiufuable.IsAssignableFrom(typeChinese);//True

    2》IsInstanceOfType(实例对象)

    判断括号中的实例对象是否当前类型的实例。(注意:父类类型、接口类型、当前类型都可以

    1             //动态创建对象(含有无参构造函数)
    2             object objChinese = Activator.CreateInstance(typeChinese);
    3 
    4             bool b1 = typeChinese.IsInstanceOfType(objChinese);//True
    5             bool b2 = typePerson.IsInstanceOfType(objChinese);//True
    6             bool b3 = typeIXiufuable.IsInstanceOfType(objChinese);//True

     3》IsSubclassOf(Type)

     判断当前类型是否是括号中类型的子类。(注意:父类可以,但是接口不行

    1             bool b1 = typeChinese.IsSubclassOf(typePerson);//True
    2             bool b2 = typeChinese.IsSubclassOf(typeIXiufuable);//False

     4》IsAbstract属性

     判断当前类型是否是抽象的。(注意:抽象的:是指只要不能实例化就是,比如:静态类、密封类、接口等

    1             Console.WriteLine(typeChinese.IsAbstract);//True
    2             Console.WriteLine(typePerson.IsAbstract);//True
    3             Console.WriteLine(typeIXiufuable.IsAbstract);//False
    4             Console.WriteLine(typeAbsClass.IsAbstract);//False
  • 相关阅读:
    P1144 最短路计数 题解 最短路应用题
    C++高精度加减乘除模板
    HDU3746 Teacher YYF 题解 KMP算法
    POJ3080 Blue Jeans 题解 KMP算法
    POJ2185 Milking Grid 题解 KMP算法
    POJ2752 Seek the Name, Seek the Fame 题解 KMP算法
    POJ2406 Power Strings 题解 KMP算法
    HDU2087 剪花布条 题解 KMP算法
    eclipse创建maven项目(详细)
    maven的作用及优势
  • 原文地址:https://www.cnblogs.com/xiaoxiaogogo/p/3573622.html
Copyright © 2011-2022 走看看