C#反射 入门学习 01
前言
获取方法的相关信息的两种形式
反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象;
在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表;该方法的两种形式:
MethodInfo [] GetMethods()
MethodInfo [] GetMethods(BindingFlags bindingflas) :它的参数带有一些限制 BindingFlags 是一个枚举
枚举成员 [DeclaredOnly,Instance ,Public] 枚举成员的功能使用 在编译器中使用"."符号后自己认真观察 【相信你很快能够理解】
ParameterInfo[] GetParameters() 方法返回一个方法的参数列表
下面用到的类 MyClass ,为了方便阅读,我把它折叠了!
1 class MyClass 2 { 3 int x; 4 int y; 5 public MyClass(int i, int j) 6 { 7 this.x = i; 8 this.y = j; 9 } 10 public int Sum() 11 { 12 return x + y; 13 } 14 public bool IsBetween(int i) 15 { 16 if (x < i && i < y) 17 { 18 return true; 19 } 20 return false; 21 } 22 public void Set(int a, int b) 23 { 24 x = a; 25 y = b; 26 } 27 public void Set(double a, double b) 28 { 29 x = (int)a; 30 y = (int)b; 31 } 32 public void Show() 33 { 34 Console.WriteLine("x: " + x + " y: " + y); 35 } 36 }
Main:
1 Type t = typeof(MyClass);//获得一个表示MyClass类的Type对象 2 Console.WriteLine("获取当前成员的名称" + t.Name); 3 Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 4 Console.WriteLine("支持的方法"); 5 #region 第一种形式 6 //MethodInfo[] mi = t.GetMethods();//显示Class类中被支持的方法 7 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 //方法GetMethods() 把 MyClass 的基类 object方法都显示出来了 9 //下面我们说说 GetMethods() 的另外一种形式,有限制的显示 10 #endregion 11 #region 第二种形式 12 MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); 13 #endregion 14 foreach (MethodInfo m in mi) 15 { 16 //返回后打印出MyClass类中成员的类型(方法的返回值类型)极其方法名称 17 Console.Write(" " + m.ReturnType.Name + " " + m.Name + " (");//ReturnType获取此方法的返回类型 18 ParameterInfo[] pi = m.GetParameters();//获得方法的参数 19 for (int i = 0; i < pi.Length; i++) 20 { 21 Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name);//ParameterType 获取该参数的Type(类型) 22 if (i+1<pi.Length) 23 { 24 Console.Write(", "); 25 } 26 27 } 28 Console.WriteLine(")"); 29 Console.WriteLine(); 30 } 36 38 Console.ReadKey();
使用反射调用方法
上面 讨论了怎么获取一个类型所支持的方法,然而为我们获取对方法的调用做了充分的准备!
MethodInfo类中的Invoke() 方法提供了该技能!
它的一种形式: object Invoke(object obj,object [] paramenters)
obj 是一个对象引用,将调用它所指向的对象上的方法,对于static方法,obj必须为null。
所有需要传递给方法的参数都必须在parameters数组中指定。如果方法不需要参数,则paramenters必须为null
基类MethodBase的 Invoke()方法返回被调用方法的返回值
请看下面的事例:
MyClass类Set()方法有所改变:
1 public void Set(int a, int b) 2 { 3 Console.WriteLine("Set(int,int)"); 4 x = a; 5 y = b; 6 Show(); 7 } 8 public void Set(double a, double b) 9 { 10 Console.WriteLine("Set(double,double)"); 11 x = (int)a; 12 y = (int)b; 13 Show(); 14 }
应用程序代码!
1 Type t = typeof(MyClass); 2 MyClass reflectOb = new MyClass(10, 20); 3 int val; 4 Console.WriteLine("Invoke methods in " + t.Name);//调用MyClass类的方法 5 Console.WriteLine(); 6 MethodInfo[] mi = t.GetMethods(); 7 8 foreach (MethodInfo m in mi)//调用每个方法 9 { 10 //获得方法参数 11 ParameterInfo[] pi = m.GetParameters(); 12 if (m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].ParameterType==typeof(int)) 13 { 14 // 指定 System.String.Compare(System.String,System.String) 和 System.String.Equals(System.Object) 15 // 方法的某些重载要使用的区域、大小写和排序规则。 16 //StringComparison.Ordinal 使用序号排序规则比较字符串 17 object[] obj = new object[2]; 18 obj[0] = 9; 19 obj[1] = 18; 20 m.Invoke(reflectOb, obj); 21 } 22 else if (m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].ParameterType==typeof(double)) 23 { 24 object[] obj = new object[2]; 25 obj[0] = 1.12; 26 obj[1] = 23.4; 27 m.Invoke(reflectOb, obj); 28 } 29 else if (m.Name.Equals("Sum",StringComparison.Ordinal)) 30 { 31 val = (int)m.Invoke(reflectOb, null); 32 Console.WriteLine("Sum is : " + val); 33 } 34 else if (m.Name.Equals("IsBetween", StringComparison.Ordinal)) 35 { 36 object[] obj = new object[1]; 37 obj[0] = 14; 38 if ((bool)m.Invoke(reflectOb, obj)) 39 { 40 Console.WriteLine("14 is between x and y"); 41 } 42 } 43 else if (m.Name.Equals("Show",StringComparison.Ordinal)) 44 { 45 m.Invoke(reflectOb,null); 46 } 47 }
详细地址 :http://www.mhprofessional.com/product.php?cat=112&isbn=007174116X&cat=112