从程序集获得类型

  先说点题外话,现在技术真的发展太快了。我这边还很多东西半生不熟

呢,那边又出现了好多有趣的新东西让你眼红不已。学还是不学这还真是

个问题。Node.js 、bootstrap,我最近刚发现的新技术,其实他们已经

存在很久了,只是没有接触过而已。昨天晚上看Node.js一下子看到两点

多,感觉真是太有意思了^,有兴趣的可以去看看,大家多交流交流.

  好了不废话了,在前面的示例中,几乎全部的MyClass信息都是通过反射得到的,但是有一个例外:

MyClass类型本身。虽然前面的示例可以动态确定MyClass的信息,但它们仍基于以下事实:事先知道

类型名MyClass,并且在typeof语句中使用它创建一个Type对象。尽管这种方式可能在很多环境中都有

用,但是要发挥反射的全部功能,就必须能通过分析其他程序集的内容动态的获取可用的类型。

  程序集提供了它包含的类和结构的信息。借助反射应用程序接口,可以加载程序集,获取它的相

关信息并创建其公共可用类型的实例。通过使用这种机制,程序能够搜素其环境,利用那些潜在的功能而

无需在编译期间显示的定义他们。由于类型的全部信息都可以被发现,因此不存在反射应用的内在限制。

为了获取程序集的相关信息,首先需要创建一个Assembly对象。Assembly类并没有定义公有的

构造函数,它的对象实例是通过类的一个方法获得的。这里使用的LoadFrom()方法可以加载由文件名

指定的程序集,其形式如下:

  static Assembly LoadFrom(string fileName)

一旦获得了Assembly类型的对象,就可以通过调用该对象的GetType()来得到它所定义的类型

。基本形式如下:

  Type[] GetTypes()

  此方法返回一个数组,它包含了程序集的类型。

  为了说明如何获取程序集的类型,我们需要在解决方案中添加一个类库,类库名字为MyClasses,

在类库中添加三个类:MyClass、AnotherClass、Demo。代码如下:

程序集MyClasses代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace MyClasses
{
public class MyClass
{
int x;
int y; public MyClass(int i)
{
Console.WriteLine("一个参数的构造函数:");
x = y = i;
}
public MyClass(int i, int j)
{
Console.WriteLine("两个参数构造函数:");
x = i;
y = j; Show();
} public int Sum()
{
return x + y;
} public bool IsBetween(int i)
{
if (x < i && i < y)
return true;
else
return false;
} public void Set(int a, int b)
{
Console.Write("函数:Set(int a, int b)");
x = a;
y = b; Show();
} public void Set(double a, double b)
{
Console.Write("函数:Set(double a, double b)"); x = (int)a;
y = (int)b; Show();
} public void Show()
{
Console.WriteLine("x:{0},y:{1}", x, y);
} } public class AnotherClass
{
string msg; public AnotherClass(string msg)
{
this.msg = msg;
} public void show() {
Console.WriteLine(msg);
}
}
public class Demo
{
public void test()
{
Console.WriteLine("我是打酱油的!!");
}
}
}

使用反射代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
class Program
{
static void Main(string[] args)
{ ReflectAssemblyDemo();
Console.ReadKey();
} static void ReflectAssemblyDemo()
{
int val; Assembly asm = Assembly.LoadFrom("MyClasses.dll"); Type[] allTypes = asm.GetTypes(); foreach (Type type in allTypes)
{
Console.WriteLine("程序集中找到类:" + type.Name);
}
Console.WriteLine(); //使用第一个类
Type t = allTypes[]; Console.WriteLine("使用类:" + t.Name); //获得构造函数
ConstructorInfo[] ci = t.GetConstructors(); //显示此类中的构造函数
Console.WriteLine("此类中的构造函数有:"); foreach (ConstructorInfo c in ci)
{
Console.Write(" " + t.Name + " ("); ParameterInfo[] pi = c.GetParameters(); for (int i = ; i < pi.Length; i++)
{
Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name); if (i + < pi.Length) Console.Write(",");
} Console.WriteLine(")");
} //获取匹配的构造函数 int x; for (x = ; x < ci.Length; x++)
{
ParameterInfo[] pi = ci[x].GetParameters();
if (pi.Length == ) break;
} if (ci.Length == x)
{
Console.WriteLine("没有匹配的构造函数");
return;
}
else
{
object[] consargs = new object[]; consargs[] = ;
consargs[] = ; object reflectOb = ci[x].Invoke(consargs); Console.WriteLine("通过reflectOb调用方法"); Console.WriteLine(); MethodInfo[] mi = t.GetMethods(); foreach (MethodInfo m in mi)
{
//获得方法参数 ParameterInfo[] pi = m.GetParameters(); if (m.Name.CompareTo("Set") == && pi[].ParameterType == typeof(int))
{
object[] args = new object[]; args[] = ;
args[] = ; m.Invoke(reflectOb, args);
}
else if (m.Name.CompareTo("Set") == && pi[].ParameterType == typeof(double))
{
object[] args = new object[]; args[] = 1.25;
args[] = 7.5; m.Invoke(reflectOb, args);
}
else if (m.Name.CompareTo("Sum") == )
{
val = (int)m.Invoke(reflectOb, null); Console.WriteLine("Sum is {0}", val);
}
else if (m.Name.CompareTo("IsBetween") == )
{
object[] args = new object[]; args[] = ; if ((bool)m.Invoke(reflectOb, args))
{
Console.WriteLine("13 is between x and y");
} }
else if (m.Name.CompareTo("Show") == )
{
m.Invoke(reflectOb, null);
}
}
}
}
}
}

运行结果:

  自此,反射部分基本内容写完了.希望对大家有所帮助.现在正在进行WPF开发,我会把在项目开发中遇到的问题与解决方案及时与您分享,希望您能继续关注.

  最后,如果本文对您有所帮助,请点推荐,谢谢!

C#基础知识回顾-- 反射(4)的更多相关文章

  1. C#基础知识回顾-- 反射(3)

    C#基础知识回顾-- 反射(3)   获取Type对象的构造函数: 前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”, 其他没有什么可以写的了,前两篇主要是铺垫, ...

  2. C#基础知识回顾-- 反射(1)

    C#基础知识回顾-- 反射(1)   反射(reflection)是一种允许用户获得类型信息的C#特性.术语“反射”源自于它的工作方式: Type对象映射它所代表的底层对象.对Type对象进行查询可以 ...

  3. C#基础知识回顾-- 反射(2)

    使用反射调用方法: 一旦知道一个类型所支持的方法,就可以对方法进行调用.调用时,需使用包含在   MethodInfo中的Invoke()方法.调用形式:   object Invoke(object ...

  4. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

  5. C#基础知识回顾--线程传参

    C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...

  6. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  7. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  8. C++ 基础知识回顾总结

    一.前言 为啥要写这篇博客?答:之前学习的C和C++相关的知识,早就被自己忘到一边去了.但是,随着音视频的学习的不断深入,和C/C++打交道的次数越来越多,看代码是没问题的,但是真到自己操刀去写一些代 ...

  9. scrapy实战1,基础知识回顾和虚拟环境准备

        视频地址 https://coding.imooc.com/learn/list/92.html   一. 基础知识回顾     1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...

随机推荐

  1. jquery中siblings方法配合什么方法一起使用

    siblings() 获得匹配集合中每个元素的同胞,通过选择器进行筛选是可选的.接下来通过本文给大家介绍jQuery siblings()用法实例详解,需要的朋友参考下吧 siblings() 获得匹 ...

  2. 2019.02.16 bzoj5466: [Noip2018]保卫王国(链分治+ddp)

    传送门 题意简述: mmm次询问,每次规定两个点必须选或者不选,求树上的带权最小覆盖. 思路: 考虑链分治+ddpddpddp 仍然是熟悉的套路,先考虑没有修改的状态和转移: 令fi,0/1f_{i, ...

  3. boost--内存池

    boost的内存池实现了一个快速.紧凑的内存分配和管理器,使用它可以完全不用考虑delete释放问题.常用的boost内存池有pool.object_pool.singleton_pool. 1.po ...

  4. VsCode编写和调试.NET Core

    本文转自:https://www.cnblogs.com/Leo_wl/p/6732242.html 阅读目录 使用VsCode编写和调试.NET Core项目 回到目录 使用VsCode编写和调试. ...

  5. ECharts初体验

    ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等) ...

  6. MFC:Tab控件嵌入对话框

    1.先建立一个对话框MFC应用程序,然后在工具箱里面把Tab Control控件放到对话框中的合适位置上. 再在对话框类中,声明一个CTabCtrl变量: CTabCtrl m_tab; 变量m_ta ...

  7. Android-普通变量与普通方法内存图

    描述Worker对象: package android.java.oop11; // 描述Worker public class Worker { public String name; public ...

  8. WeexSDK源码分析(iOS)

    0.从工作原理谈起 Weex 表面上是一个客户端技术,但实际上它串联起了从本地开发.云端部署到分发的整个链路.开发者首先可在本地像编写 web 页面一样编写一个 app 的界面,然后通过命令行工具将之 ...

  9. 背水一战 Windows 10 (83) - 用户和账号: 数据账号的添加和管理, OAuth 2.0 验证

    [源码下载] 背水一战 Windows 10 (83) - 用户和账号: 数据账号的添加和管理, OAuth 2.0 验证 作者:webabcd 介绍背水一战 Windows 10 之 用户和账号 数 ...

  10. 【设计经验】1、Verilog中如何规范的处理inout信号

    在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号).比如,IIC总线中的SDA信号就是一个双向信号,QSPI Flash的四线操作的时候四根信号线均为双向信号. ...