您的位置:首页 > 编程语言 > C#

C#学习笔记(十):反射

2015-07-13 18:33 597 查看

反射

放射是指在程序运行时动态的获取类的信息的机制,我们下面来看看C#中的反射。

Type


Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。 使用 Type 的成员获取关于类型声明的信息,如构造函数、方法、字段、属性 (Property) 和类的事件,以及在其中部署该类的模块和程序集。


我们获取一个指定类型的Type有三种方法:

通过typeof直接获取;

通过调用GetType方法获取;

通过调用Type的静态方法GetType获取;

这三个方法都可以获取指定类型的Type对象,但是也有一点区别,具体可以参考下面两篇博客:

http://www.studyofnet.com/news/284.html

http://blog.csdn.net/letianok/article/details/7257117

下面我们来看一个例子:

using System;

namespace Study
{
class Program
{
static void Main(string[] args)
{
Type t1 = typeof(string);
Console.WriteLine(t1.FullName);
//System.String

Type t2 = "hello type!".GetType();
Console.WriteLine(t2.FullName);
//System.String

Type t3 = Type.GetType("System.String", false);
Console.WriteLine(t3.FullName);
//System.String

Console.Read();
}
}
}


获取类的信息

我们可以通过Type类型获取到类的所有信息,比如我们要获取类的所有方法信息的话,可以使用下面的代码:

using System;
using System.Reflection;

namespace Study
{
class Program
{
static void Main(string[] args)
{
string str = "Hello Type!";

Type t = str.GetType();
//获取所有方法信息
MethodInfo[] methodInfos = t.GetMethods();
for (int i = 0; i < methodInfos.Length; i++)
{
Console.WriteLine(methodInfos[i].Name);
}
//仅获取非静态的公共方法信息
methodInfos = t.GetMethods(BindingFlags.Instance | BindingFlags.Public);
for (int i = 0; i < methodInfos.Length; i++)
{
Console.WriteLine(methodInfos[i].Name);
}

Console.Read();
}
}
}


更多信息的获取方法可以参考帮助文档(https://msdn.microsoft.com/zh-cn/library/system.type(v=vs.110).aspx)。

调用指定的方法

下面我们看看如何获取一个类的指定方法并进行调用:

using System;
using System.Reflection;

namespace Study
{
class Program
{
static void Main(string[] args)
{
string str = "Hello Type!";

Type t = str.GetType();
//对于存在多个重载的方法需要指明参数的类型
MethodInfo method = t.GetMethod("Split", new []{typeof(char[])});
//调用方法
string[] strs = method.Invoke(str, new object[] {new[] {' '}}) as string[];
for (int i = 0; i < strs.Length; i++)
{
Console.WriteLine(strs[i]);
}

Console.Read();
}
}
}


Assembly

程序集可以看做一个或多个DLL或EXE文件的集合,可以通过程序集将重复的代码提取出来,可以重复使用。

我们首先创建一个类库项目,代码如下:

namespace StudyLib
{
public class MyClass
{
public int Add(int a, int b)
{
return a + b;
}

public int Add(int a, int b, int c)
{
return a + b + c;
}
}
}


然后点击菜单栏-》生成-》生成XXX,可以获得对应的DLL文件,接下来我们使用Assembly读取DLL并执行其中的方法:

using System;
using System.Reflection;

namespace Study
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom("E:\\study\\C#\\StudyLib\\StudyLib\\bin\\Debug\\StudyLib.dll");

//输出所有类型名称
Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i].FullName);
}
//StudyLib.MyClass

//动态创建类并调用其中的方法
Type t = assembly.GetType("StudyLib.MyClass");
ConstructorInfo constructor = t.GetConstructor(Type.EmptyTypes);
Object myClass = constructor.Invoke(new object[]{});

MethodInfo method1 = t.GetMethod("Add", new[] {typeof (int), typeof (int)});
int result1 = (int)method1.Invoke(myClass, new object[] {100, 123});
Console.WriteLine("第一个方法返回: " + result1);
//第一个方法返回: 223

MethodInfo method2 = t.GetMethod("Add", new[] { typeof(int), typeof(int), typeof(int)});
int result2 = (int)method2.Invoke(myClass, new object[] { 100, 123, 456 });
Console.WriteLine("第二个方法返回: " + result2);
//第二个方法返回: 679

Console.Read();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: