首先来说一下什么是反射?

反射提供了封装程序集、模块和类型的对象(Type类型)

可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后,可以调用类型的方法或访问其字段和属性 。

总之,有了反射,以前很多实现不了的功能都可以实现。

下面先来写一个小例子,体验一下反射是怎么一回事:

打开VS2010,新建一个控制台应用程序,在program.cs里面写代码

首先引入命名空间:

using System.Reflection;

下如下代码:

         PropertyInfo len = typeof(string).GetProperty("Length");
string s = "Hello,reflection!";
int length = (int)len.GetValue(s, null);
Console.WriteLine(length.ToString());

这里通过反射获取string的Length属性,并通过调用PropertyInfo 的GetValues方法获取属性值,其中GetValues方法的原型如下:

public virtual object GetValue(object obj, object[] index);

第一个参数obj是拥有此属性的类的实例,在这个例子中,为字符串s,s拥有Length属性。

第二个参数为索引值,微软解释如下:

Optional index values for indexed properties. This value should be null for non-indexed properties.

一般情况下用null,大家可以自己深入研究一下。

GetValues方法返回的是object类型,所以必须强制转换类型。

下面通过反射来获取string的一个方法,看看方法是如何通过反射得到的,代码如下:

string s = "Hello,reflection!";
MethodInfo method = typeof(string).GetMethod("Contains");
bool result = (bool)method.Invoke(s, new object[] { "Hello" });
Console.WriteLine(result);

其中,Invoke的方法定义如下:

public object Invoke(object obj, object[] parameters);

这个就很好理解了,第一个参数为拥有此方法的类的实例,还是为string实例s.

第二个参数就是一个object数组的参数。

这里调用的是string中的Contains方法,判断string中是否包含某个字符串。

下面通过反射来实例化一个string对象,代码如下:

     Type t = Type.GetType("System.String");
char[] para = new char[] { 'H', 'e', 'l', 'l', 'o' };
var o = Activator.CreateInstance(t, para);
Console.WriteLine(o);

这个跟获取方法相似,唯一不同的就是string的构造方法参数是char[]数组,所以必须传入符合的类型。这里实例化了一个string,值为Hello。

看到这里,你对反射已经有了初步的了解,下面开始进入实战应用:

在解决方案上面点击鼠标右键,添加项目,选中类库,输入名称,添加一个类库。

在类库中添加Custom类,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ReflectionDll
{
public class Custom
{
public string Name { get; set; }
public string Address { get;set; }
public int Age { get; set; }
public DateTime BirthDay { get; set; } public string GetInfo(string name = "",int age = )
{
if (name == "" && age == )
{
return "Custom Name: " + this.Name + ",Age: " + this.Age;
}
else
{
return "Custom Name: " + name + ",Age: " + age;
}
}
}
}

这里只声明了几个属性和一个方法,供演示使用。写好后编译一下,在控制台项目里面添加引用这个类库(为了方便,否则每次编译都要手动拷贝DLL到控制台项目下面),这样VS会自动将生成的DLL拷贝到控制台debug目录下,方便调用。下面开始使用反射来加载这个DLL,代码如下:

        string path = Environment.CurrentDirectory + "\\ReflectionDll.dll";
Assembly assem = Assembly.LoadFile(path);
Type customType = assem.GetType("ReflectionDll.Custom");
var custom = Activator.CreateInstance(customType);

注意了,这里首先要获取DLL的物理路径,所以上面是否添加引用是无所谓的。有了路径后,通过Assembly的LoadFile方法加载DLL,再获取类的Type,注意GetType方法里面的参数必须为类的全称,及命名空间 + 类名,否则无法找到。

最后一行,创建了一个类的实例,类型为object类型。

下面来获取Custom的所有属性,代码如下:

 PropertyInfo[] propertys = customType.GetProperties();

         Console.WriteLine("******************************");
foreach (PropertyInfo pro in propertys)
{
Console.WriteLine("PropertyName:" + pro.Name + "\n" +
"PropertyType:" + pro.PropertyType + "\n" +
"ClassName:" + pro.ReflectedType + "\n" +
"DLLName:" + pro.Module + "\n");
}
Console.WriteLine("******************************");

通过调用GetProperties方法获取所有属性,保存到PropertyInfo[]数组中,然后遍历数组输出属性值。

下面是各个属性的含义:

Name                      属性名称

PropertyType          属性数据类型

ReflectedType         所在的类的命名控件 + 类名

Module                  所在的DLL文件名称

设置某个属性的值,方法如下:

     PropertyInfo p = customType.GetProperty("Name");
p.SetValue(custom, "CustomName",null);

是不是很容易啊。。。

下面来说一下,调用类的方法,和一些属性。代码如下:

         MethodInfo _method = customType.GetMethod("GetInfo");
//显示方法名称
Console.WriteLine("Invoke method:" + _method.Name);
//显示返回的数据类型
Console.WriteLine("Return type:" + _method.ReturnParameter);
ParameterInfo[] parameters = _method.GetParameters();
foreach (ParameterInfo pa in parameters)
{
Console.WriteLine(pa.Name + pa.ParameterType + pa.Position + pa.Member);
} object[] paras = new object[] { "Jack", }; Console.WriteLine(_method.Invoke(custom, paras));
同属性一样,参数可以通过GetParameters()来获取,获取的参数信息如下:

Name                参数名称
ParameterType 参数数据类型
Position 参数的位置
Member 输出所有参数 调用有参数的方法时,需要传入参数,New一个object数组,将参数按顺序写入即可。 补充内容:
当类中存在重载方法时,直接获取方法名会报异常,可以通过参数来获取指定的重载方法:
MethodInfo _method = customType.GetMethod("GetInfo",new Type[] {typeof(string),typeof(int)});

												

C#反射基础知识和实战应用的更多相关文章

  1. Java__线程---基础知识全面实战---坦克大战系列为例

    今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的jav ...

  2. java反射基础知识(四)反射应用实践

    反射基础 p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start. 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的 ...

  3. java反射基础知识(一)

    一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...

  4. Vue学习之--------消息订阅和发布、基础知识和实战应用(2022/8/24)

    文章目录 1.基础知识 2.代码实例 2.1 main.js 2.2 School.vue 2.3 Student.vue 2.4 App.vue 3.全局事件总线通信改为消息的订阅和发布 3.1 核 ...

  5. java反射基础知识(五)反射应用实践

    详解Java反射各种应用   Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...

  6. java反射基础知识(三)

    原文地址:http://tutorials.jenkov.com/java-reflection/index.html http://www.cnblogs.com/penghongwei/p/329 ...

  7. java反射基础知识(二)

    1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以让我们在运行时获取类的函数.属性.父类.接口等 Class 内部信息的机制.通过反射还可以让我们在运行期实例化对象 ...

  8. Java反射基础知识

    反射机制就是可以把一个类,类的成员(属性.方法)当成一个对象来操作,也就是说,类,类的成员,我们在运行的时候可以动态的去操作它们. 所有的Java类都继承了Object类,在Object类中定义了一个 ...

  9. 第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备

    相信很多人或多或少听说了微信公众平台的火热.但是开发还是有一点门槛,鉴于挺多朋友问我怎么开发,问多了,自己平时也进行以下总结.所以下面给大家分享一下我的经验: 微信公众号是什么? 官网的介绍:再小的个 ...

随机推荐

  1. Linux下的虚拟Bridge实现

    http://www.cnblogs.com/zmkeil/archive/2013/04/21/3034733.html Linux下的Bridge也是一种虚拟设备,这多少和vlan有点相似,它依赖 ...

  2. Angular解决双向数据绑定

    <!DOCTYPE html> <html ng-app="myApp1"><body><div ng-controller=" ...

  3. 京东2017校园招聘笔试题 【第K个幸运数】

    题目描述 4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字. 前几个幸运数字为:4,7,44,47,74,77,444,447... 现在输入一个数字K,输出第 ...

  4. archlinux 安装过程记录

    2014年安装了一次,使用U盘启动安装的,但是当时网络有问题,断断续续,没有做详细记录. 现在到了杭州,重新来一次. 使用U盘安装 下载ISO :http://mirrors.163.com/arch ...

  5. jquery选择器总结 转自(永远的麦子)

    jQuery选择器总结 阅读目录 1, 基本选择器? 2, 层次选择器? 3, 过滤选择器? 4, 表单选择器? jQuery选择器共有四大类,分别为基本选择器,层次选择器,过滤选择器和表单选择器.下 ...

  6. js-正则表达式的替换

    正则表达式替换使用的是replace()方法.Replace()方法是用一些字符途欢另一些字符 语法:stringObject.replace(regexp,replacement) regexp 必 ...

  7. Java中实现PHP中的urlencode与rawurlencode

    php手册中对urlencode这样说明 在java中 URLEncoder做了这样注释 也就是说java中对星号"*"是不进行编码的 也就是说URLEncoder之后还是&quo ...

  8. python3中返回字典的键

    我在看<父与子的编程之旅>的时候,有段代码是随机画100个矩形,矩形的大小,线条的粗细,颜色都是随机的,代码如下, import pygame,sys,random from pygame ...

  9. Java多线程理解

    首先说一下进程和线程的区别 进程:是计算机运用程序实例,拥有独立的内存空间和数据(猜测内存堆应该是作用的进程上),一个进程包含多个子线程,不同进程相互独立: 线程:cpu执行的基本单位,拥有独立的寄存 ...

  10. Ubuntu12.04下编译OpenCv2.4.9程序

    引用地址http://blog.163.com/huai_jing@126/blog/static/171861983201311103411229/ 方法1:直接命令编译: g++ main.cpp ...