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 }
  • 相关阅读:
    A. Greg and Array 夜
    zoj 2314 Reactor Cooling 夜
    sgu 104. Little shop of flowers 夜
    C. Greg and Friends 夜
    sgu 103. Traffic Lights 夜
    B. Greg and Graph 夜
    B. Yaroslav and Two Strings 夜
    zoj 2313 Chinese Girls' Amusement 夜
    sgu 101. Domino 夜
    hdu 4532 湫秋系列故事——安排座位 夜
  • 原文地址:https://www.cnblogs.com/hammerc/p/4608365.html
Copyright © 2011-2022 走看看