zoukankan      html  css  js  c++  java
  • C#学习笔记(十):反射

    反射

    放射是指在程序运行时动态的获取类的信息的机制,我们下面来看看C#中的反射。

    Type

    Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。 使用 Type 的成员获取关于类型声明的信息,如构造函数、方法、字段、属性 (Property) 和类的事件,以及在其中部署该类的模块和程序集。

    我们获取一个指定类型的Type有三种方法:

    1. 通过typeof直接获取;
    2. 通过调用GetType方法获取;
    3. 通过调用Type的静态方法GetType获取;

    这三个方法都可以获取指定类型的Type对象,但是也有一点区别,具体可以参考下面两篇博客:

    http://www.studyofnet.com/news/284.html

    http://blog.csdn.net/letianok/article/details/7257117

    下面我们来看一个例子:

     1 using System;
     2 
     3 namespace Study
     4 {
     5     class Program
     6     {
     7         static void Main(string[] args)
     8         {
     9             Type t1 = typeof(string);
    10             Console.WriteLine(t1.FullName);
    11             //System.String
    12 
    13             Type t2 = "hello type!".GetType();
    14             Console.WriteLine(t2.FullName);
    15             //System.String
    16 
    17             Type t3 = Type.GetType("System.String", false);
    18             Console.WriteLine(t3.FullName);
    19             //System.String
    20 
    21             Console.Read();
    22         }
    23     }
    24 }

    获取类的信息

    我们可以通过Type类型获取到类的所有信息,比如我们要获取类的所有方法信息的话,可以使用下面的代码:

     1 using System;
     2 using System.Reflection;
     3 
     4 namespace Study
     5 {
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             string str = "Hello Type!";
    11 
    12             Type t = str.GetType();
    13             //获取所有方法信息
    14             MethodInfo[] methodInfos = t.GetMethods();
    15             for (int i = 0; i < methodInfos.Length; i++)
    16             {
    17                 Console.WriteLine(methodInfos[i].Name);
    18             }
    19             //仅获取非静态的公共方法信息
    20             methodInfos = t.GetMethods(BindingFlags.Instance | BindingFlags.Public);
    21             for (int i = 0; i < methodInfos.Length; i++)
    22             {
    23                 Console.WriteLine(methodInfos[i].Name);
    24             }
    25 
    26             Console.Read();
    27         }
    28     }
    29 }

    更多信息的获取方法可以参考帮助文档(https://msdn.microsoft.com/zh-cn/library/system.type(v=vs.110).aspx)。

    调用指定的方法

    下面我们看看如何获取一个类的指定方法并进行调用:

     1 using System;
     2 using System.Reflection;
     3 
     4 namespace Study
     5 {
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             string str = "Hello Type!";
    11 
    12             Type t = str.GetType();
    13             //对于存在多个重载的方法需要指明参数的类型
    14             MethodInfo method = t.GetMethod("Split", new []{typeof(char[])});
    15             //调用方法
    16             string[] strs = method.Invoke(str, new object[] {new[] {' '}}) as string[];
    17             for (int i = 0; i < strs.Length; i++)
    18             {
    19                 Console.WriteLine(strs[i]);
    20             }
    21 
    22             Console.Read();
    23         }
    24     }
    25 }

    Assembly

    程序集可以看做一个或多个DLL或EXE文件的集合,可以通过程序集将重复的代码提取出来,可以重复使用。

    我们首先创建一个类库项目,代码如下:

     1 namespace StudyLib
     2 {
     3     public class MyClass
     4     {
     5         public int Add(int a, int b)
     6         {
     7             return a + b;
     8         }
     9 
    10         public int Add(int a, int b, int c)
    11         {
    12             return a + b + c;
    13         }
    14     }
    15 }

    然后点击菜单栏-》生成-》生成XXX,可以获得对应的DLL文件,接下来我们使用Assembly读取DLL并执行其中的方法:

     1 using System;
     2 using System.Reflection;
     3 
     4 namespace Study
     5 {
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             Assembly assembly = Assembly.LoadFrom("E:\study\C#\StudyLib\StudyLib\bin\Debug\StudyLib.dll");
    11 
    12             //输出所有类型名称
    13             Type[] types = assembly.GetTypes();
    14             for (int i = 0; i < types.Length; i++)
    15             {
    16                 Console.WriteLine(types[i].FullName);
    17             }
    18             //StudyLib.MyClass
    19 
    20             //动态创建类并调用其中的方法
    21             Type t = assembly.GetType("StudyLib.MyClass");
    22             ConstructorInfo constructor = t.GetConstructor(Type.EmptyTypes);
    23             Object myClass = constructor.Invoke(new object[]{});
    24 
    25             MethodInfo method1 = t.GetMethod("Add", new[] {typeof (int), typeof (int)});
    26             int result1 = (int)method1.Invoke(myClass, new object[] {100, 123});
    27             Console.WriteLine("第一个方法返回: " + result1);
    28             //第一个方法返回: 223
    29 
    30             MethodInfo method2 = t.GetMethod("Add", new[] { typeof(int), typeof(int), typeof(int)});
    31             int result2 = (int)method2.Invoke(myClass, new object[] { 100, 123, 456 });
    32             Console.WriteLine("第二个方法返回: " + result2);
    33             //第二个方法返回: 679
    34 
    35             Console.Read();
    36         }
    37     }
    38 }
  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/hammerc/p/4608365.html
Copyright © 2011-2022 走看看