博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NET反射系统
阅读量:6209 次
发布时间:2019-06-21

本文共 5196 字,大约阅读时间需要 17 分钟。

   没事看书的笔记,虽然这些知识在项目中经常用,但是系统的看看书也对得起这买书的钱。。。

 

Type

 

    查看msdn知道反射的所有东西都是在Reflection中,想获取什么就去自己查查相关的类就好了,用了反射这么久,觉得其实核心就是那个Type。

 

   Type派生于MemberInfo这个抽象类。其实想想,当你获取到了一个Type对象的时候,那么就应该能点出什么得到这个对象的名称,属性,方法这些,所以整个反射系统都是这样的,所以没必要去每个类和方法都看,用的时候右键转到定义看看就好。

 

 

static void Main(string[] args)         {
//不管什么,先得到Type Type t = typeof(A); Console.WriteLine("类型名称:{0}", t.Name); //得到类型中的字段集合,但是私有的字段不会被我们获取到 //所以大牛们或者老师们都苦口良心的说重要私有的东西都private Console.WriteLine(); FieldInfo[] fields = t.GetFields(); foreach (FieldInfo f in fields) {
//FieldInfo还有很多东西,需要用的时候右键转到定义看看就行 Console.WriteLine("{1} Field:{0}", f.Name, f.IsPublic ? "Public" : "Private"); } //获取下Type中的方法,有道词典查查方法这个单词,原来是method,那么应该有个MethodInfo这个类吧 MethodInfo[] methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static); foreach (MethodInfo m in methods) {
Console.Write("{0} {1}", m.IsPublic ? "Public" : "Private", m.Name); //获取下方法的参数 StringBuilder pstr = new StringBuilder(); ParameterInfo[] par = m.GetParameters(); foreach (ParameterInfo p in par) {
pstr.AppendFormat(",{0} {1}", p.ParameterType.Name, p.Name); } Console.Write("({0})", pstr.ToString() != string.Empty ? pstr.ToString().Substring(1) : string.Empty); //获取返回值 Console.Write(" return {0}", m.ReturnType.Name); Console.WriteLine(); } Console.WriteLine(); Console.Read(); } public class A {
public string name; public string name1; private Int32 sum; public void Show() {
Console.WriteLine(this.name); } public static Int32 Test(Int32 i) {
return i; } }

 

注意这里把基类object的方法成员也显示了。

可以根据枚举值来限定获取的方法

public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr);

获取公开静态的方法

MethodInfo[] methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static);

   注意这里:假如只写个公开的枚举值,那么就无法获取到方法,应该至少包含 是否静态或实例枚举值和是否公开枚举值。

 

反射调用方法

 

public abstract class MethodBase

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

   假如要调用的方法是实例方法,那么第一个参数就是对象,静态方法就是null,后面的是参数集合。

static void Main(string[] args)         {
//不管什么,先得到Type A a = new A(); Type t = a.GetType(); Console.WriteLine("类型名称:{0}", t.Name); //获取下Type中的方法,有道词典查查方法这个单词,原来是method,那么应该有个MethodInfo这个类吧 MethodInfo[] methods = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);//过滤掉父类的方法 foreach (MethodInfo m in methods) {
//调用方法 if (m.Name == "Show") m.Invoke(a, new object[] { "hello" }); Console.WriteLine(); } Console.WriteLine(); Console.Read(); } public class A {
public void Show(string name) {
Console.WriteLine(name); } }

调用构造函数创建类型对象

   前面的例子都是自己手动创建个类型对象,这样还不如直接去调用那些方法。

当在有些特殊的需求中需要在运行时来创建对象,这样反射的优势就体现出来了。

反射创建对象其中的一个方法就是去调用类型的构造函数。

注意这个方法返回的是object

public object Invoke(object[] parameters);

 

 

static void Main(string[] args)         {
//不管什么,先得到Type A a = new A(); Type t = a.GetType(); Console.WriteLine("类型名称:{0}", t.Name); //获取类型的构造函数,这里我们只需要创建一个默认构造函数的对象,所以构造函数的参数为0 object obj = null; ConstructorInfo[] Con = t.GetConstructors(); foreach (ConstructorInfo c in Con) {
if (c.GetParameters().Length == 0) {
obj = c.Invoke(null); } } //现在我们将obj转换成类型A if (obj != null) {
A a1 = obj as A; a1.Show("abc"); } else Console.WriteLine("糟糕!"); Console.WriteLine(); Console.Read(); } public class A {
public void Show(string name) {
Console.WriteLine(name); } }

通过程序集来获取类型对象

   前面的情况都是建立在我们知道A这个类,反射的功能是超级强大的,当你不知道一个程序集中有那些类型对象,那么用反射去寻找程序集中的类型。

程序集这个类中有很多加载程序集的方法,请选择最适合当前情况的。

public static Assembly Load(string assemblyString);

public static Assembly LoadFile(string path);

public static Assembly LoadFrom(string assemblyFile);

上面这3个还有很多重载的方法,所以要具体去了解那么就去msdn看吧。

 

static void Main(string[] args)         {
//通过程序集获取类型对象 Assembly asm = Assembly.Load("ConsoleApplication2"); Type[] type = asm.GetTypes(); foreach (Type t in type) {
Console.WriteLine("类型名称:{0}", t.Name); } Console.WriteLine(); Console.Read(); } public class A {
public void Show(string name) {
Console.WriteLine(name); } } public class B { }

 

 

到这里,其实你已经想到了可以自己完成一个程序,比如全自动类型查询。

 

 

作者:海不是蓝

博客:http://www.cnblogs.com/hailan2012/

邮箱:hailan2012@sina.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/hailan2012/archive/2012/02/18/2357551.html

你可能感兴趣的文章
【工具使用系列】关于 MATLAB 遗传算法与直接搜索工具箱,你需要知道的事
查看>>
Kali-linux Arpspoof工具
查看>>
PDF文档页面如何重新排版?
查看>>
基于http协议使用protobuf进行前后端交互
查看>>
UML设计一个电影票务销售系统(四)
查看>>
AlphaGo Zero用它来调参?【高斯过程】到底有何过人之处?
查看>>
Linux平台Oracle多个实例启动说明
查看>>
bash腳本編程之三 条件判断及算数运算
查看>>
php cookie
查看>>
linux下redis安装
查看>>
Sqlserver表值函数
查看>>
弃 Java 而使用 Kotlin 的你后悔了吗?| kotlin将会是最好的开发语言
查看>>
JavaScript 数据类型
查看>>
量子通信和大数据最有市场突破前景
查看>>
StringBuilder用法小结
查看>>
UVa 10252-Common Permutation
查看>>
CSS - 修改input - placeholder 和 readonly 的样式
查看>>
Revel运行APP出现的路径问题
查看>>
android studio :cannot resolve symbol R
查看>>
paper 20 :color moments
查看>>