在上一篇里,我们叨逼了好多如何获取到程序集里的对象,但是对象有了,还不知道怎么调,OK,下面开始干这个对象:

首先,我们对上一篇的对象做了一些修改,以适应多种情况:

 using System;
using System.Collections.Generic;
using System.Linq; namespace PersonMoudle
{
public class Person
{
public Person()
{
Name = "Sirius";
Age = ;
Height = ;
Sex = "Middle";
}
public Person(string name, int age, float height, string sex)
{
Name = name;
Age = age;
Height = height;
Sex = sex;
} public string Name { get; set; }
public int Age { get; set; }
public float Height { get; set; }
public string Sex { get; set; } #region Void
/// <summary>
/// 说话方法
/// </summary>
/// <param name="words"></param>
public void Speak(string words)
{
Console.WriteLine(words);
}
/// <summary>
/// 打电话方法
/// </summary>
/// <param name="telto">打给谁</param>
/// <param name="words">说什么</param>
public void TelSomeone(string telto, string words)
{
Console.WriteLine("Hi " + telto + ", This is sirius speaking! " + words);
} /// <summary>
/// 叫爹方法
/// </summary>
public void SayHi()
{
Console.WriteLine("Hi, Dad!");
}
#endregion private string GetMyName()
{
return Name.Trim();
} public string GetMySex()
{
return Sex;
} public List<string> BeenCity()
{
return new List<string>
{
"Beijing",
"Jinan",
"NewYork"
};
} public List<string> BennCity(int count)
{
return new List<string>
{
"Beijing",
"Jinan",
"NewYork"
}.Take(count).ToList();
}
}
}

Person类

然后,我们在另一个项目里load这个dll,用反射调用有参数、无参数的构造函数/有参数、无参数的方法,以及拿到他们的返回值:

 using System;
using System.Linq;
using System.Reflection; namespace ReflectionTest
{
class Program
{
static void Main(string[] args)
{ /*
How to use reflect to invoke a method, we've these steps:
* 1.Get assembly of your moudle
* 2.Get the type that you want to use(here is Person type)
* 3.Build a instance of this type(instance可以理解为一个实例,就相当于实例化一个对象)
* 4.Call Method.Invoke method to invoke it with the instance in step 3.
*/
//OK, 我们按照步骤一步一步来: //step 1. 你也可以用上一篇里的方式,直接去拿类型
Assembly assembly = Assembly.LoadFrom("PersonMoudle.dll");
var name = assembly.GetName();
Console.WriteLine(name); //step 2. 这里偷个懒,我们其实知道自己写的PersonMoudle里,只有一种类型,就是Person类型,所以我们只找Person类型
var types = assembly.GetTypes();//These're all types in PersonMoudle.dll
var personType = types.FirstOrDefault(t => t.Name.Equals("Person"));//You need check personType 'if not null' then to use. //step 3. See, we build it already. var instance = assembly.CreateInstance(personType.FullName, false); //step 4(1), 我们来调用一个无参数的、void的方法(SayHi),这个应该是最简单的了
//根据第一篇的代码,我们需要首先拿到Person这个type中,所有可能用到的方法(这里用BindingFlags过滤了一些,但是觉得这样的写法不好,有更好方法的朋友欢迎告知,多谢!)
var personMethods = personType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Where(m => !m.Attributes.ToString().Contains("Special"));
var methodSayHi = personMethods.FirstOrDefault(m => m.Name.Equals("SayHi"));//我们定位到SayHi方法
Console.WriteLine("SayHi方法的执行结果:");
methodSayHi.Invoke(instance, null);//使用invoke方法去call,可以看到SayHi方法Console.WriteLine的结果。
Console.WriteLine("SayHi方法的执行结束================");
Console.WriteLine(Environment.NewLine); //step 4(2), 再来调用一个有参数,void的方法(Speak)。
Console.WriteLine("Speak方法执行结果:");
var methodSpeak = personMethods.FirstOrDefault(m => m.Name.Equals("Speak"));
methodSpeak.Invoke(instance, new[] {"This is the speak method invoked."});
Console.WriteLine("Speak方法的执行结束================");
Console.WriteLine(Environment.NewLine); //var a = new {words = "Come, let's fuck", telto = "BaoBao"}; //step 4(3), so...多个参数呢?聪明的你一定想得到
Console.WriteLine("TelSomeone方法,打电话给隔壁包小姐");
var methodTelSomeone = personMethods.FirstOrDefault(m => m.Name.Equals("TelSomeone"));
methodTelSomeone.Invoke(instance, new []{"Miss Bao","Could come to my house?"});//谁知道怎么打乱参数位置调用?
//notice: new[]{}这样的写法会自动推断强类型,如果有类型不同的参数,请使用new object[]{}的写法。
Console.WriteLine("呼叫包小姐结束,先不写了,我离开一会。。。");
Console.WriteLine(Environment.NewLine); //step 4(4), 有返回值的,这段真是太水了,哈哈
Console.WriteLine("GetMySex方法,拿返回值");
var methodGetMySex = personMethods.FirstOrDefault(m => m.Name.Equals("GetMySex"));
var resultGetMySex = methodGetMySex.Invoke(instance, null);
Console.WriteLine("我的性别是:" + resultGetMySex);
Console.WriteLine(Environment.NewLine); //but if……构造函数有参数的呢?
//思路:在上面我们写了反射的步骤,说白了就是先找到类型,然后实例化(通过反射),然后调用方法。我们我们应该尝试在构建instance的时候传入构造函数参数。事实证明,我的猜想是对的。
//PARAMS: string name, int age, float height, string sex
var con = personType.GetConstructor(new[] { typeof(string), typeof(int), typeof(float), typeof(string) });//我们找到指定的构造函数
var instanceWithParams = con.Invoke(new object[] { "Sirius", , , "我不是人妖" });//这里拿到这个构造函数的实例
Console.WriteLine("GetMySex方法,拿返回值(使用指定构造函数)");
var resultGetMySex1 = methodGetMySex.Invoke(instanceWithParams, null);
Console.WriteLine("我的性别是:" + resultGetMySex1);
Console.WriteLine(Environment.NewLine); //通过查看.NET FRAMEWORK已经开放的源码,我们看到Assembly.CreateInstance方法实际上是调用了Activator.CreateInstance方法。我们当然也可以通过直接调用这个激活器,用another way去实现这种实例化。当然,无参数的实例化也是可以这么做的,.NET源码(988行):
//TODO:http://referencesource.microsoft.com/#mscorlib/system/reflection/assembly.cs,81336f4535acc832
//写法2:
var instanceNewWay = Activator.CreateInstance(personType, new object[] {"Sirius", , , "我不是人妖(new way)"});
Console.WriteLine("GetMySex方法,拿返回值(使用指定构造函数)");
var resultGetMySex2 = methodGetMySex.Invoke(instanceNewWay, null);
Console.WriteLine("我的性别是:" + resultGetMySex2);
Console.WriteLine(Environment.NewLine);
}
}
}

行了,低胸们,已然是2%的废话+98%的代码,各位,再会!

C#中反射的使用(How to use reflect in CSharp)(2)的更多相关文章

  1. JAVA中反射机制五(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  2. JAVA中反射机制六(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  3. Java中反射的三种常用方式

    Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...

  4. C#中反射接受的字符串需要满足的Backus-Naur Form语法

    MSDN的Specifying Fully Qualified Type Names指明了C#中反射接受的字符串需要满足如下的Backus-Naur Form语法. BNF grammar of fu ...

  5. .NET中反射机制的使用与分析

    .NET中反射机制的使用与分析 [日期:2008-06-30] 来源:  作者:志伟     .NET反射的定义:审查元数据并收集关于它的类型信息的能力. 元数据是一种二进制信息,用以对存储在公共语言 ...

  6. java中反射学习整理

    转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序能够訪问.检測和改动它本身的状态或行为的一种能力. jav ...

  7. 在C++中反射调用.NET(二)

    反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C+ ...

  8. 在C++中反射调用.NET(一)

    为什么要在C++中调用.NET 一般情况下,我们常常会在.NET程序中调用C/C++的程序,使用P/Invoke方式进行调用,在编写代码代码的时候,首先要导入DLL文件,然后在根据C/C++的头文件编 ...

  9. 在C++中反射调用.NET(三)

    在.NET与C++之间传输集合数据 上一篇<在C++中反射调用.NET(二)>中,我们尝试了反射调用一个返回DTO对象的.NET方法,今天来看看如何在.NET与C++之间传输集合数据. 使 ...

  10. Java中反射的实现方式

    所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制.这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field).方法(Method)以及调用其中的方法 ...

随机推荐

  1. [转]Jquery Ajax用法

    原文地址:http://www.php100.com/html/program/jquery/2013/0905/6004.html jQuery学习之jQuery Ajax用法详解 来源:   时间 ...

  2. 晶振波形、MIPI波形

    /********************************************************************************** * 晶振波形.MIPI波形 * ...

  3. 省常中模拟 Test3 Day1

    tile 贪心 题意:给出一个矩形,用不同字母代表的正方形填充,要求相邻的方块字母不能相同,求字典序(将所有行拼接起来)最小的方案. 初步解法:一开始没怎么想,以为策略是每次填充一个尽量大的正方形.但 ...

  4. poj 3469 Dual Core CPU

    题目描述:由于越来越多的计算机配置了双核CPU,TinySoft公司的首席技术官员,SetagLilb,决定升级他们的产品-SWODNIW.SWODNIW包含了N个模块,每个模块必须运行在某个CPU中 ...

  5. [Everyday Mathematics]20150203

    设 $f$ 在 $\bbR$ 上连续可导, 且 $\dps{f'\sex{\frac{1}{2}}=0}$. 试证: $$\bex \exists\ \xi\in \sex{0,\frac{1}{2} ...

  6. UI篇--Android中TableLayout中的布局

        表格布局是按照行列来组织子视图的布局.表格布局包含一系列的Tablerow对象,用于定义行(也可以使用其它子对象).表格布局不为它的行.列和单元格显示表格线.每个行可以包含个以上(包括)的单元 ...

  7. HDU 1892-See you(二维BIT)

    题意: 最多1000*1000的方格,各方格开始有一本书 有四种操作:对指定方格把书拿走或向里面放书,从一个方格那一定量的书放到另一个方格,查询给定对角线顶点的坐标的矩形范围内包含的书的总数 分析: ...

  8. POJ2987 Firing 最大权闭合图

    详情请参考http://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html 值得注意的地方,割边会把图分成两部分,一部分和起点相连,另一部 ...

  9. HDU 5278 PowMod 数论公式推导

    题意:中文题自己看吧 分析:这题分两步 第一步:利用已知公式求出k: 第二步:求出k然后使用欧拉降幂公式即可,欧拉降幂公式不需要互质(第二步就是BZOJ3884原题了) 求k的话就需要构造了(引入官方 ...

  10. C语言相关图书推荐

    C Primer Plus(第5版 中文版) 作      者 [美] 普拉塔(Prata S.) 著:云巅工作室 编 出 版 社 人民邮电出版社 出版时间 2005-02-01 版      次 1 ...