加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

反射发送实战-InvokeMember 转

发布时间:2020-12-15 04:40:12 所属栏目:百科 来源:网络整理
导读:span style="font-size: 10pt"反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能,下面是我看了《Programming C#》(O'Reilly)之后对于反射的一点实践,本想直接做个应用程序来说明问题,但苦于工作繁忙并考虑到以简单为主,故先对
<tr>
<td align="center"><span style="font-size: 10pt"></td>
</tr></table>
<span style="font-size: 10pt">//使用反射发送
ReflectionTest t = new ReflectionTest();
//计算所用时间
startTime = DateTime.Now;
for(int i = 0;i < iterations;i++)
{
t.DoOperation();
}
elasped = DateTime.Now - startTime;
Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);
Console.ReadLine();
}
}
///
/// Reflection 的摘要说明。
///

public class ReflectionTest
{
//保存动态生成并编译的类的type对象
Type theType = null;
//保存动态生成类的实例
object theClass = null;
///
/// 供Client调用的方法
///

public void DoOperation()
{
//未初始化
if(theType == null)
{
//初始化
GenerateCode();
}
//调用方法时的参数数组(此处为空)
object[] arguments = new object[0];
//调用动态生成类的方法
theType.InvokeMember("SayHello",//要调用的方法名
BindingFlags.Default|BindingFlags.InvokeMethod,//Binding标志,具体参看msdn
null,//使用默认Binding对象
theClass,//在theClass实例上调用此方法
arguments//调用方法时的参数数组
);
}
///
/// 运行时生成代码
///

private void GenerateCode()
{
//文件名
string fileName = "Test";
//打开文件,如果不存在,则创建
Stream s = File.Open(fileName + ".cs",FileMode.Create);
//创建一个StreamWriter来写入数据
StreamWriter wrtr = new StreamWriter(s);
//写入动态创建类的源代码
wrtr.WriteLine("// 动态创建Test类");
//类名
string className = "TestClass";
wrtr.WriteLine("using System;");
wrtr.WriteLine("class {0}",className);
wrtr.WriteLine("{");
wrtr.WriteLine("tpublic void SayHello()");
wrtr.WriteLine("t{");
wrtr.WriteLine("ttConsole.WriteLine("Hello,World");");
wrtr.WriteLine("t}");
wrtr.WriteLine("}");
//关闭StreamWriter和文件
wrtr.Close();
s.Close();
//启动进程编译源文件
//指定参数
ProcessStartInfo psi = new ProcessStartInfo();
//启动cmd.exe
psi.FileName = "cmd.exe";
//cmd.exe的参数,/c-close,完成后关闭;后为参数,指定cmd.exe使用csc来编译刚才生成的源文件
string compileString = "/c C:WINNTMicrosoft.NETFrameworkv1.1.4322csc.exe /optimize+ /target:library {0}.cs";
psi.Arguments = String.Format(compileString,fileName);
//运行时的风格-最小化
psi.WindowStyle = ProcessWindowStyle.Minimized;
//启动进程
Process proc = Process.Start(psi);
//指定当前在此进程退出前等待
proc.WaitForExit();
//从编译好的dll文件load一个Assembly
Assembly a = Assembly.LoadFrom(fileName + ".dll");
//创建类的实例
theClass = a.CreateInstance(className);
//取得此类实例的类型
theType = a.GetType(className);
//删除源文件
//File.Delete(flieName + ".cs");
}
}}

最后贴一个BindingFlags的Demo Share with EveryOne

using System;
using System.Reflection;
using System.IO;

namespace BindingFlagsSnippet { ??? class EntryPoint ??? { ??????? static void Main(string[] args) ??????? { ??????????? Invoke.Go(); ??????? } ??? }

??? ??? class Invoke ??? { ??????? public static void Go() ??????? { ??????????? // BindingFlags.InvokeMethod ??????????? // Call a static method. ??????????? Type t = typeof (TestClass);

??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a static method."); ??????????? Console.WriteLine("-------------------------"); ??????????? t.InvokeMember ("SayHello",BindingFlags.InvokeMethod,null,new object [] {});

??????????? // BindingFlags.InvokeMethod ??????????? // Call an instance method. ??????????? TestClass c = new TestClass (); ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking an instance method."); ??????????? Console.WriteLine("----------------------------"); ??????????? c.GetType().InvokeMember ("AddUp",c,new object [] {}); ??????????? c.GetType().InvokeMember ("AddUp",new object [] {}); ??????????? ??????????? // BindingFlags.InvokeMethod ??????????? // Call a method with parameters. ??????????? object [] args = new object [] {100.09,184.45}; ??????????? object result; ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a method with parameters."); ??????????? Console.WriteLine("---------------------------------"); ??????????? result = t.InvokeMember ("ComputeSum",args); ??????????? Console.WriteLine ("{0} + {1} = {2}",args[0],args[1],result);

??????????? // BindingFlags.GetField,SetField ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a field (getting and setting.)"); ??????????? Console.WriteLine("--------------------------------------"); ??????????? // Get a field value. ??????????? result = t.InvokeMember ("Name",BindingFlags.GetField,new object [] {}); ??????????? Console.WriteLine ("Name == {0}",result); ??????????? // Set a field. ??????????? t.InvokeMember ("Name",BindingFlags.SetField,new object [] {"NewName"}); ??????????? result = t.InvokeMember ("Name",result); ??????????? ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking an indexed property (getting and setting.)"); ??????????? Console.WriteLine("--------------------------------------------------"); ??????????? // BindingFlags.GetProperty ??????????? // Get an indexed property value. ??????????? int? index = 3; ??????????? result = t.InvokeMember ("Item",BindingFlags.GetProperty,new object [] {index}); ??????????? Console.WriteLine ("Item[{0}] == {1}",index,result); ??????????? // BindingFlags.SetProperty ??????????? // Set an indexed property value. ??????????? index = 3; ??????????? t.InvokeMember ("Item",BindingFlags.SetProperty,new object [] {index,"NewValue"}); ??????????? result = t.InvokeMember ("Item",result); ??????????? ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Getting a field or property."); ??????????? Console.WriteLine("----------------------------"); ??????????? // BindingFlags.GetField ??????????? // Get a field or property. ??????????? result = t.InvokeMember ("Name",BindingFlags.GetField | BindingFlags.GetProperty,result); ??????????? // BindingFlags.GetProperty ??????????? result = t.InvokeMember ("Value",new object [] {}); ??????????? Console.WriteLine ("Value == {0}",result);

??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a method with named parameters."); ??????????? Console.WriteLine("---------------------------------------"); ??????????? // BindingFlags.InvokeMethod ??????????? // Call a method using named parameters. ??????????? object[] argValues = new object [] {"Mouse","Micky"}; ??????????? String [] argNames = new String [] {"lastName","firstName"}; ??????????? t.InvokeMember ("PrintName",argValues,argNames);

??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a default member of a type."); ??????????? Console.WriteLine("------------------------------------"); ??????????? // BindingFlags.Default ??????????? // Call the default member of a type. ??????????? Type t3 = typeof (TestClass2); ??????????? t3.InvokeMember ("",BindingFlags.InvokeMethod | BindingFlags.Default,new TestClass2(),new object [] {}); ? ??????????? // BindingFlags.Static,NonPublic,and Public ??????????? // Invoking a member by reference. ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking a method by reference."); ??????????? Console.WriteLine("-------------------------------"); ??????????? MethodInfo m = t.GetMethod("Swap"); ??????????? args = new object[2]; ??????????? args[0] = 1; ??????????? args[1] = 2; ??????????? m.Invoke(new TestClass(),args); ??????????? Console.WriteLine ("{0},{1}",args[1]); ??????????? // The string is case-sensitive. ??????????? Type type = Type.GetType("System.String");

??????????? // Check to see if the value is valid. If the object is null,the type does not exist. ??????????? if (type == null) ??????????? { ??????????????? Console.WriteLine("Please ensure that you specify only valid types in the type field."); ??????????????? Console.WriteLine("The type name is case-sensitive."); ??????????????? return; ??????????? } ??????????? // Declare and populate the arrays to hold the information. ??????????? // You must declare either NonPublic or Public with Static or the search will not work. ??????????? FieldInfo [] fi = type.GetFields (BindingFlags.Static | ??????????????? BindingFlags.NonPublic | BindingFlags.Public);? ??????????? // BindingFlags.NonPublic ??????????? MethodInfo [] miNonPublic = type.GetMethods (BindingFlags.Static | ??????????????? BindingFlags.NonPublic); ??????????? // BindingFlags.Public ??????????? MethodInfo [] miPublic = type.GetMethods (BindingFlags.Static | ??????????????? BindingFlags.Public);

??????????? // Iterate through all the nonpublic methods. ??????????? foreach (MethodInfo method in miNonPublic) ??????????? { ??????????????? Console.WriteLine(method); ??????????? } ??????????? // Iterate through all the public methods. ??????????? foreach (MethodInfo method in miPublic) ??????????? { ??????????????? Console.WriteLine(method); ??????????? } ??????????? // Iterate through all the fields. ??????????? foreach (FieldInfo f in fi) ??????????? { ??????????????? Console.WriteLine(f); ??????????? }

??????????? // BindingFlags.Instance ??????????? // Call an instance method. ??????????? TestClass tc = new TestClass (); ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking an Instance method."); ??????????? Console.WriteLine("----------------------------"); ??????????? tc.GetType().InvokeMember ("AddUp",BindingFlags.Public | ??????????????? BindingFlags.Instance | BindingFlags.CreateInstance, ??????????????? null,tc,new object [] {});

??????????? // BindingFlags.CreateInstance ??????????? // Calling and creating an instance method. ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking and creating an instance method."); ??????????? Console.WriteLine("-----------------------------------------"); ??????????? tc.GetType().InvokeMember ("AddUp",new object [] {});

??????????? // BindingFlags.DeclaredOnly ??????????? TestClass tc2 = new TestClass(); ??????????? Console.WriteLine(); ??????????? Console.WriteLine("DeclaredOnly members"); ??????????? Console.WriteLine("---------------------------------"); ??????????? System.Reflection.MemberInfo[] memInfo = ??????????????? tc2.GetType().GetMembers(BindingFlags.DeclaredOnly); ??????????? for(int i=0;i

??????????? // BindingFlags.SuppressChangeType ??????????? TestClass obj = new TestClass(); ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Invoking static method - PrintName"); ??????????? Console.WriteLine("---------------------------------"); ??????????? System.Reflection.MethodInfo methInfo = ??????????????? obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.SuppressChangeType | ??????????????? BindingFlags.InvokeMethod,new object[] ??????????????? {"Brad","Smith"},null);

??????????? // BindingFlags.IgnoreCase ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Using IgnoreCase and invoking the PrintName method."); ??????????? Console.WriteLine("---------------------------------------------------"); ??????????? methInfo = obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.IgnoreCase | ??????????????? BindingFlags.InvokeMethod,new object[] ??????????????? {"brad","smith"},null);

??????????? // BindingFlags.IgnoreReturn ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Using IgnoreReturn and invoking the PrintName method."); ??????????? Console.WriteLine("-----------------------------------------------------"); ??????????? methInfo = obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.IgnoreReturn | ??????????????? BindingFlags.InvokeMethod,null);

??????????? // BindingFlags.OptionalParamBinding ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Using OptionalParamBinding and invoking the PrintName method."); ??????????? Console.WriteLine("-------------------------------------------------------------"); ??????????? methInfo = obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.OptionalParamBinding | ??????????????? BindingFlags.InvokeMethod,null);

??????????? // BindingFlags.ExactBinding ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Using ExactBinding and invoking the PrintName method."); ??????????? Console.WriteLine("-----------------------------------------------------"); ??????????? methInfo = obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.ExactBinding | ??????????????? BindingFlags.InvokeMethod,null); ? ??????????? // BindingFlags.FlattenHierarchy ??????????? Console.WriteLine(); ??????????? Console.WriteLine("Using FlattenHierarchy and invoking the PrintName method."); ??????????? Console.WriteLine("---------------------------------------------------------"); ??????????? methInfo = obj.GetType().GetMethod("PrintName"); ??????????? methInfo.Invoke(obj,BindingFlags.FlattenHierarchy | ??????????????? BindingFlags.InvokeMethod,null); ??????? } ??? }

??? public class TestClass ??? { ??????? public String Name; ??????? private Object [] values = new Object [] {0,1,2,3,4,5,6,7,8,9};

??????? public Object this [int index] ??????? { ??????????? get ??????????? { ??????????????? return values[index]; ??????????? } ??????????? set ??????????? { ??????????????? values[index] = value; ??????????? } ??????? }

??????? public Object Value ??????? { ??????????? get ??????????? { ??????????????? return "the value"; ??????????? } ??????? }

??????? public TestClass () ??????? { ??????????? Name = "initialName"; ??????? }

??????? int methodCalled = 0;

??????? public static void SayHello () ??????? { ??????????? Console.WriteLine ("Hello"); ??????? }

??????? public void AddUp () ??????? { ??????????? methodCalled++; ??????????? Console.WriteLine ("AddUp Called {0} times",methodCalled); ??????? }

??????? public static double ComputeSum (double d1,double d2) ??????? { ??????????? return d1 + d2; ??????? }

??????? public static void PrintName (String firstName,String lastName) ??????? { ??????????? Console.WriteLine ("{0},lastName,firstName); ??????? }

??????? public void PrintTime () ??????? { ??????????? Console.WriteLine (DateTime.Now); ??????? }

??????? public void Swap(ref int a,ref int b) ??????? { ??????????? int x = a; ??????????? a = b; ??????????? b = x; ??????? } ??? }

??? [DefaultMemberAttribute ("PrintTime")] ??? public class TestClass2 ??? { ??????? public void PrintTime () ??????? { ??????????? Console.WriteLine (DateTime.Now); ??????? } ??? } }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

<span style="font-size: 10pt">反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能,下面是我看了《Programming C#》(O'Reilly)之后对于反射的一点实践,本想直接做个应用程序来说明问题,但苦于工作繁忙并考虑到以简单为主,故先对反射发送(reflection emit)的使用做一些介绍。文章最后再给出一个实例。
下面的程序在运行时生成了一个Test.cs文件,并调用csc编译成Test.dll文件,然后利用Type.InvokeMember()方法调用其中的SayHello()方法,然后和原始方法对比一下性能。
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace InvokeMember
{
///
/// Class1 的摘要说明。
///

class Class1 { ///
/// 应用程序的主入口点。
///

[STAThread]
static void Main(string[] args)
{
//循环次数
const int iterations = 100;
//计算所用时间
DateTime startTime = DateTime.Now;
for(int i = 0;i< iterations;i++) { //对照方法
Console.WriteLine("Hello,World");
}
TimeSpan elasped = DateTime.Now - startTime;
Console.WriteLine("Looping Elapsed milliseconds:" + elasped.TotalMilliseconds + "for {0} iterations",iterations);
<table height="18" cellspacing="0" cellpadding="0" width="470" border="0">

    推荐文章
      热点阅读