C#中反射的使用(How to use reflect in CSharp)(2)

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

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

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4
 5 namespace PersonMoudle
 6 {
 7     public class Person
 8     {
 9         public Person()
10         {
11             Name = "Sirius";
12             Age = 25;
13             Height = 172;
14             Sex = "Middle";
15         }
16         public Person(string name, int age, float height, string sex)
17         {
18             Name = name;
19             Age = age;
20             Height = height;
21             Sex = sex;
22         }
23
24         public string Name { get; set; }
25         public int Age { get; set; }
26         public float Height { get; set; }
27         public string Sex { get; set; }
28
29         #region Void
30         /// <summary>
31         /// 说话方法
32         /// </summary>
33         /// <param name="words"></param>
34         public void Speak(string words)
35         {
36             Console.WriteLine(words);
37         }
38         /// <summary>
39         /// 打电话方法
40         /// </summary>
41         /// <param name="telto">打给谁</param>
42         /// <param name="words">说什么</param>
43         public void TelSomeone(string telto, string words)
44         {
45             Console.WriteLine("Hi " + telto + ", This is sirius speaking! " + words);
46         }
47
48         /// <summary>
49         /// 叫爹方法
50         /// </summary>
51         public void SayHi()
52         {
53             Console.WriteLine("Hi, Dad!");
54         }
55         #endregion
56
57         private string GetMyName()
58         {
59             return Name.Trim();
60         }
61
62         public string GetMySex()
63         {
64             return Sex;
65         }
66
67         public List<string> BeenCity()
68         {
69             return new List<string>
70             {
71                 "Beijing",
72                 "Jinan",
73                 "NewYork"
74             };
75         }
76
77         public List<string> BennCity(int count)
78         {
79             return new List<string>
80             {
81                 "Beijing",
82                 "Jinan",
83                 "NewYork"
84             }.Take(count).ToList();
85         }
86     }
87 }

Person类

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

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

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

时间: 2024-08-01 20:58:04

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

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

一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段,方法和构造函数对其底层对等进行操作. 二.java.lang.reflect AccessibleObject类 java.lang.reflect.AccessibleObject类是Field,Method和Constructor类对象的基类. 它提供了将反射对象标记为在使用它时抑制默认Java

Java语言中反射动态代理接口的解释与演示

Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

java中反射学习整理

转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序可以访问,检测和修改它本身的状态或行为的一种能力. java中反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装载,无须在组件之间进行链接.反射允许在编写与执行时,使程序能够接入到jvm中的类的内部信息,而不是源代码中选定的类协作的代码.这使反射成为构建灵活应用代码的主要工具.需要注意的是,如果使用不当,反射的成本会很高. package

java中反射

反射 避免硬编码 类对象 (存储了类的信息的对象 类加载的产物) Class 类名.class 直接获得类对象 (简单类型的类对象 int.class) 类的对象.getClass() Class.forName("类名") 通过类名主动加载一个类并获得类对象 类对象.newInstance() 创建类的对象 java中反射,布布扣,bubuko.com

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

反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C++与.NET程序集之间传递复杂对象. 先看看.NET程序集的一个返回对象的方法: public IUserInfo GetUserByID(int userId) { IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>(); user

android中反射技术使用实例

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义.反射 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.Java 的反射机制的实现要借助于4个类:class,Constructor,Field,

Java中反射的实现方式

所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制.这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field).方法(Method)以及调用其中的方法,也可以设置其中的属性值. 在Java中实现反射最重要的一步,也是第一步就是获取Class对象,得到Class对象后可以通过该对象调用相应的方法来获取该类中的属性.方法以及调用该类中的方法. Java中反射有如下几种实现方式: 1.通过Class.forName()方法加载字符串,就可以得到该字符串

Java中反射机制(Reflection)研究及源码演示

如下内容内容是关于 Java中反射机制(Reflection)研究及演示的内容. package com.jiangqq.reflection; import java.lang.reflect.Method; public class Reflection1 { public static void main(String[] args) throws Exception { Class<?> tClass = Class.forName("java.lang.Class"

JAVA反射系列之Field,java.lang.reflect.Field使用获取方法

JAVA反射系列之Field,java.lang.reflect.Field使用获取方法.   转载https://my.oschina.net/u/1407116/blog/209383 摘要 java.lang.reflect.Field使用 Field. 首先必须明一点 Field类主要是用来辅助获取和操作类的属性的! 1.怎么通过反射获取类的属性 先来看JDK提供的方法有如下几种: a)Class.getDeclaredField(String name);      返回一个 Fiel

Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别(转)

一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:  其中 i.加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构.即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!.