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

 

获取Type对象的构造函数:

  前一篇因为篇幅问题因为篇幅太短被移除首页,反射这一块还有一篇“怎样在程序集中使用反射”,

其他没有什么可以写的了,前两篇主要是铺垫,在实际应用中,主要是最后两篇。其实写完反射,

我也考虑重新把委托重新写下,现在想想确实太过单一和简单了。我会把实际开发中委托的例子多写几个

, 以便以理解。如果这几篇C#的基础对您有所帮助的话,请点击推荐。谢谢您的支持……

  好了,不废话了,在前面例子中,由于MyClass类型的对象是显示创建的,因此使

用反射技术来调用MyClass上的方法没有任何优势--以普通的方式调用对象上的方法会简单的多。但是,

如果对象是在运行时动态创建的,反射的功能就显示出来了。在这种情况下,需要首先获取一个构造函

数列表,然后再调用列表中的某个构造函数,创建一个该类型的实例。通过这种机制,可以在运行时实例

化任意类型的对象而不必在声明中指定。

  为了获得某个类型的构造函数,需要调用Type对象上的GetConstructors()。常用形式为:

  ConstructorInfo[] GetConstructors()

  该方法返回一个描述构造函数的ConstructorInfo对象数组。ConstructorInfo中常用的

是GetParamters()方法,该方法返回给定构造函数的参数列表。

  一旦找到了合适的构造函数,就调用ConstructorInfo定义的Invoke()方法来创建对象:

  object Invoke(object[] args)

  需要传递给此方法的所有参数都在args中指定。如果不需要参数,args必须为null。另外,

args必须包含与参数个数相同的元素,并且实参的类型必须与形参的类型兼容。Invoke()方法返回

的是指向新构造对象的引用。

例子:

测试对象类

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);
}
}

使用反射:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
class Program
{
static void Main(string[] args)
{
InvokeConsDemo();
Console.ReadKey();
} static void InvokeConsDemo()
{ Type t = typeof(MyClass); int val; ConstructorInfo[] ci = t.GetConstructors(); Console.WriteLine("类构造函数如下:"); foreach (ConstructorInfo c in ci)
{
Console.Write("" + t.Name + "("); ParameterInfo[] pi = c.GetParameters(); for (int i = 0; i < pi.Length; i++)
{
Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name); if (i + 1 < pi.Length) Console.Write(", ");
}
Console.WriteLine(") "); }
Console.WriteLine(); int x; for (x = 0; x < ci.Length; x++)
{
ParameterInfo[] pi = ci[x].GetParameters(); if (pi.Length == 2) break;
} if (x == ci.Length)
{
Console.WriteLine("没有找到两个参数的构造函数"); return;
}
else
{
object[] consargs = new object[2]; consargs[0] = 10;
consargs[1] = 20; 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") == 0 && pi[0].ParameterType == typeof(int))
{
object[] args = new object[2]; args[0] = 12;
args[1] = 7; m.Invoke(reflectOb, args);
}
else if (m.Name.CompareTo("Set") == 0 && pi[0].ParameterType == typeof(double))
{
object[] args = new object[2]; args[0] = 1.25;
args[1] = 7.5; m.Invoke(reflectOb, args);
}
else if (m.Name.CompareTo("Sum") == 0)
{
val = (int)m.Invoke(reflectOb, null); Console.WriteLine("Sum is {0}",val);
}
else if (m.Name.CompareTo("IsBetween") == 0)
{
object[] args = new object[1]; args[0] = 13; if ((bool)m.Invoke(reflectOb, args))
{
Console.WriteLine("13 is between x and y");
} }
else if (m.Name.CompareTo("Show") == 0)
{
m.Invoke(reflectOb, null);
}
} }
}
}
}

运行结果为:

  本例中,找到了一个两个参数的构造函数,那么使用下面的语句实例化了一个该类型的对象:

object reflectOb=ci[x].Invoke(consargs);

调用Invoke()方法后,reflectOb将引用一个MyClass类型的对象。此后,程序将执行

reflectOb上的方法。

注意:本例为了简单起见,假设了一个使用两个参数的构造函数,并且两个参数都为int类型

。但在实际的应用程序中,必须检验每一个参数的类型。

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

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

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

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

    从程序集获得类型 先说点题外话,现在技术真的发展太快了.我这边还很多东西半生不熟 呢,那边又出现了好多有趣的新东西让你眼红不已.学还是不学这还真是 个问题.Node.js .bootstrap,我最近 ...

  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. POJ3687——Labeling Balls(反向建图+拓扑排序)

    Labeling Balls DescriptionWindy has N balls of distinct weights from 1 unit to N units. Now he tries ...

  2. Android 设定activity的进入和退出效果

    看了android的源代码和资源文件,终于明白如何去修改设置Dialog和Activity的进入和退出效果了.设置Dialog首先通过 getWindow()方法获取它的窗口,然后通过getAttri ...

  3. 游标-Oracle游标汇总

    游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作.    游标可分为:    <!--[if !supportLists] ...

  4. ADT中的代码补全设置

    设置自动补全代码 刚刚学Android,有很多变量和方法 都不熟悉.需要有提示,才更加方便. 快捷方式:Alt + /    可以出现代码提示. 默认的只有输入“ .” 以后才会有代码补全提示,可作如 ...

  5. Eclipse优化

    未特别说明,以下均处理在Window->Preferences下 General列表下 Startup and Shutdown可以去掉一些不必要的启动项 怎样才能知道哪些启动项有用呢?我现在把 ...

  6. JAX-RS入门 二 :运行

    上一节,已经成功的定义了一个REST服务,并且提供了具体的实现,不过我们还需要把它运行起来. 在上一节的装备部分,列举了必须的jar(在tomcat中运行)和可选的jar(作为一个独立的应用程序运行) ...

  7. RPi 2B GPIO 测试

    /************************************************************************************** * RPi 2B GPI ...

  8. ☀Chrome模拟移动端浏览器

  9. 常用高度——获取浏览器窗口的高度(jquery和js)

    一:针对浏览器的常用高度 jquery的用法: <script type="text/javascript"> $(document).ready(function() ...

  10. Linux shell 获取当前时间之前N天

    date +%Y%m%d --date '2 days ago' 更多资料关注:www.kootest.com ;技术交流群:182526995