反射的定义

反射提供了描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。------摘自MSDN

自我理解

看到反射二字,自然而然的会想到,小时候拿着一面镜子,反射阳光玩。其实

反射就好比一面镜子,通过它我们能在不显示引用程序集的情况下,一窥程序集内的“风景”。

利用好反射这把利器,我们在开发中就能体会到荀老夫子所言的,君子性非异也,善假于物也

本文主要包括以下四节:

通过反射调用类的构造函数(有参/无参)

通过反射调用类的静态方法(有参/无参)

通过反射调用类的非静态方法(有参/无参)

通过反射调用类的含有ref参数的方法

代码示例:

 namespace TestDLL
{
using System.Linq; public class TestClass
{
private int _priValue; //无参构造函数
public TestClass()
{
this._priValue = ;
} //有参构造函数
public TestClass(int i)
{
this._priValue = i;
} //无参方法
public int Add()
{
return ++this._priValue;
} //ref参数的方法
public void Exchange(ref int a, ref int b)
{
int temp = b;
b = a;
a = temp;
} // 静态有参方法
public static string SayHi(string name)
{
return "Hi~ " + name;
} public static int AddValue(int[] objsInts)
{
int temp = ;
if (objsInts != null)
{
temp += objsInts.Sum();
}
return temp;
}
}
}

通过反射调用代码示例:

    static void Main(string[] args)
{
//加载程序集(dll文件地址),使用Assembly类
Assembly testDll = Assembly.LoadFile(Environment.CurrentDirectory + "\\TestDLL.dll"); //获取类型,参数(名称空间+类)
Type testClass = testDll.GetType("TestDLL.TestClass"); //创建实例
var instance = testDll.CreateInstance("TestDLL.TestClass"); //调用无参构造函数
ConstructorInfo noParamConstructor = testClass.GetConstructor(Type.EmptyTypes);
object testClassObject = noParamConstructor.Invoke(new object[] { }); //调用有参构造函数
ConstructorInfo paramConstructor = testClass.GetConstructor(new Type[] { Type.GetType("System.Int32") });
object testClassObject2 = paramConstructor.Invoke(new object[] { }); #region 调用非静态方法
MethodInfo addMethod = testClass.GetMethod("Add");
object addValue = addMethod.Invoke(instance, new object[] { });
#endregion #region 调用静态有参方法
MethodInfo sayHiMethod = testClass.GetMethod("SayHi");
object sayHi = sayHiMethod.Invoke(null, new object[] { "jason" });
#endregion #region 调用含有ref参数的方法
MethodInfo exchange = testClass.GetMethod("Exchange");
var objs = new object[];
objs[] = ;
objs[] = ;
Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[], objs[]);
object retValue = exchange.Invoke(instance, objs);
#endregion #region 调用参数为数组的方法
MethodInfo addValueInfo = testClass.GetMethod("AddValue");
var ints = new int[] {, , , , };
object obj = addValueInfo.Invoke(null, new object[] {ints});
#endregion Console.WriteLine("MethodInfo.Invoke() Example\n");
Console.WriteLine("TestClass.Add() returned: {0}", addValue);
Console.WriteLine("TestClass.SayHi() returned:{0}", sayHi);
Console.WriteLine("TestClass.Exchange(ref int a,ref int b) returned:{0}", retValue);
Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[], objs[]); Console.WriteLine("AddValue(int[] objsInts) result:{0}", obj);
}

在此对代码中红色加粗的方法做注(摘自MSDN):

MethodBase.Invoke 方法 (Object, Object[])

使用指定的参数调用当前实例所表示的方法或构造函数。

语法

public Object Invoke(

Object obj,

Object[] parameters

)

参数

obj

类型:System.Object

对其调用方法或构造函数的对象。 如果方法是静态的,则忽略此参数。 如果构造函数是静态的,则此参数必须为 null 或定义该构造函数的类的实例。

若要使用其 MethodInfo 对象来调用静态方法,请将 null 传递给 obj。

parameters

类型:System.Object[]

调用的方法或构造函数的参数列表。 这是一个对象数组,这些对象与要调用的方法或构造函数的参数具有相同的数量、顺序和类型。 如果没有任何参数,则 parameters 应为 null。

如果此实例所表示的方法或构造函数采用 ref 参数(在 Visual Basic 中为 ByRef),使用此函数调用该方法或构造函数时,该参数不需要任何特殊属性。 如果此数组中的对象未用值来显式初始化,则该对象将包含该对象类型的默认值。 对于引用类型的元素,该值为 null。 对于值类型的元素,该值为 0、0.0 或 false,具体取决于特定的元素类型。

返回值

类型:System.Object

一个对象,包含被调用方法的返回值,如果调用的是构造函数,则为 null。

C# 反射之调用方法谈的更多相关文章

  1. C# 知识点笔记:IEnumerable<>的使用,利用反射动态调用方法

    IEnumerable<T>的使用 创建一个IEnumerable对象 List<string> fruits = new List<string> { " ...

  2. golang 反射中调用方法

    反射中调用函数 众所周知,golang中的函数是可以像普通的int.float等类型变量那样作为值的,例如: package main import "fmt" func hell ...

  3. 利用java反射动态调用方法,生成grid数据

    项目中需要java后台查询并组装前台grid的数据,数据行数不定,数据行定义不定,开始用了最原始的方法,写了几百行,就是前台需要什么字段后台拼接什么字段,java代码冗余量非常大,并且不够灵活,一旦前 ...

  4. golang通过反射动态调用方法

    func Call(m map[string]interface{}, name string, params ...interface{}) ([]reflect.Value, error) { f ...

  5. Guava动态调用方法

    前言 大家在Coding的时候,经常会遇到这样一个情况,根据不同的条件去执行对应的代码.我们通常的处理方式是利用if-else判断,或者直接switch-case,特别是jdk1.6之后,swith开 ...

  6. 利用反射调用方法时,处理ref,out参数需要注意的问题(转)

    转自:http://www.68idc.cn/help/buildlang/ask/20150318283817.html 项目中如下的泛型方法,因为要在运行时,动态指定类型参数,所以要利用反射来实现 ...

  7. java对过反射调用方法

      public class InvokeTester { public InvokeTester() { } String str; public InvokeTester(String str) ...

  8. .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)——转载

    原文链接:https://blog.walterlv.com/post/dotnet-high-performance-reflection-suggestions.html ***** 大家都说反射 ...

  9. C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法

    使用反射(Reflect)获取dll文件中的类型并调用方法 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static v ...

随机推荐

  1. iOS开发——高级篇——音频、音乐播放(封装类)

    一.简介 简单来说,音频可以分为2种音效又称“短音频”,通常在程序中的播放时长为1~2秒在应用程序中起到点缀效果,提升整体用户体验 音乐比如游戏中的“背景音乐”,一般播放时间较长 播放音频可以使用框架 ...

  2. 2016年11月27日--面向对象:多态、类库、委托、is和as运算符、泛型集合

    1.虚方法 virtual 重写 override 父类中的方法,在子类中并不适用,那么子类需要自主更改继承的方法或者是属性,那父类中加了virtual关键字的方法才可以被子类重写,子类重写父类的方法 ...

  3. EL算术表达式

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  4. java23

    1:多线程(理解)    (1)多线程:一个应用程序有多条执行路径        进程:正在执行的应用程序        线程:进程的执行单元,执行路径        单线程:一个应用程序只有一条执行 ...

  5. Effective Python2 读书笔记2

    Item 14: Prefer Exceptions to Returning None Functions that returns None to indicate special meaning ...

  6. linux 服务

    CentOS 7.x设置自定义开机启动,添加自定义系统服务 http://linux.it.net.cn/CentOS/fast/2015/0507/15184.html

  7. [python面向对象]--基础篇

    1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...

  8. 不用写Windows服务实现定时器功能(FluentScheduler )

    MacBook Pro 只有四个 USB Type-C 接口是否错了? 一项新技术的诞生总会对已存在的事物造成冲击或影响,如果大家都害怕冲击与影响,那这个世界永远像现在不变就行了,大家都好好的,待在自 ...

  9. 标准模板库(STL)的一个 bug

    今天敲代码的时候遇到 STL 的一个 bug,与 C++ 的类中的 const 成员变量有关.什么,明明提供了默认的构造函数和复制构造函数,竟然还要类提供赋值运算符重载.怎么会这样? 测试代码 Tes ...

  10. Oracle的索引适用范围

    若字段数据的重复率不是很高,而且数据量不是很大,考虑B树索引: 若字段数据的重复率较高,而且查询中有特定的查询方式(比如列之间有或,与等逻辑运算),则考虑位图索引: 若对列中的字段进行模糊查询或者语言 ...