public delegate String MyMethod(String str);
private void GenerateMethod()
{
Type[] argsType = { typeof(String) };
DynamicMethod dm = new DynamicMethod("MyMethod1",
typeof(String),
argsType,
typeof(Form1).Module);//public string MyMethod1(string s)
ILGenerator il = dm.GetILGenerator();//{
il.Emit(OpCodes.Ldstr, "hello:");//string a="hello:";
il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上
il.Emit(OpCodes.Call, typeof(String).GetMethod("Concat", new Type[] { typeof(String), typeof(String) }));//string.Concat(a,s);
il.Emit(OpCodes.Ret);//return string.Concat(a,s);}
MyMethod myMethod = (MyMethod)dm.CreateDelegate(typeof(MyMethod));
MessageBox.Show(myMethod("my friends"));
}
private void GenerateMethodTwo()
{
DynamicMethod dm = new DynamicMethod("Test", null,
new Type[] { typeof(string) }, typeof(string).Module);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上
MethodInfo call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
il.Emit(OpCodes.Call, call);//执行Console.WriteLine方法
il.Emit(OpCodes.Ret);//结束返回
Action<string> test = (Action<string>)dm.CreateDelegate(typeof(Action<string>));
test("henry");
//下面Test1方法和Test完成的方法是一样的,但IL似乎有些不同.
//主要体现变量设置,对于变量的位置也会影响指令
dm = new DynamicMethod("Test1", null,
new Type[] { typeof(string) }, typeof(string).Module);
il = dm.GetILGenerator();
il.DeclareLocal(typeof(string));//定义变量
il.Emit(OpCodes.Ldarg_0);//把参数推到堆栈上
il.Emit(OpCodes.Stloc_0);//把值保存到索引为0的变量里
il.Emit(OpCodes.Ldloc_0);//把索引为0的变量推到堆栈上
call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
il.Emit(OpCodes.Call, call);//执行Console.WriteLine方法
il.Emit(OpCodes.Ret);
test = (Action<string>)dm.CreateDelegate(typeof(Action<string>));
test("henry");
//对于下面的方法大家自己推一下,其实很简单.
//如果看起来有不明白,不防copy到vs.net上然后看指令描述信息:)
dm = new DynamicMethod("Test2", null,
new Type[] { typeof(string) }, typeof(string).Module);
il = dm.GetILGenerator();
il.DeclareLocal(typeof(string));//声明一个string局部变量
il.Emit(OpCodes.Ldstr, "你好 ");//推送一个字符串引用
il.Emit(OpCodes.Ldarg_0);//把索引为0参数推到堆栈上
call = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });
il.Emit(OpCodes.Call, call);
il.Emit(OpCodes.Stloc_0);//得到的值存入局部变量
il.Emit(OpCodes.Ldloc_0);//加载局部变量到堆栈
call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
il.Emit(OpCodes.Call, call);
il.Emit(OpCodes.Ret);//执行方法
test = (Action<string>)dm.CreateDelegate(typeof(Action<string>));
test("henry");
//Console.Read();
}
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Globalization;
public class Test
{
// Declare a delegate type that can be used to execute the completed
// dynamic method.
private delegate int HelloDelegate(string msg, int ret);
public static void Main()
{
// Create an array that specifies the types of the parameters
// of the dynamic method. This dynamic method has a String
// parameter and an Integer parameter.
Type[] helloArgs = {typeof(string), typeof(int)};
// Create a dynamic method with the name "Hello", a return type
// of Integer, and two parameters whose types are specified by
// the array helloArgs. Create the method in the module that
// defines the String class.
DynamicMethod hello = new DynamicMethod("Hello",
typeof(int),
helloArgs,
typeof(string).Module);
// Create an array that specifies the parameter types of the
// overload of Console.WriteLine to be used in Hello.
Type[] writeStringArgs = {typeof(string)};
// Get the overload of Console.WriteLine that has one
// String parameter.
MethodInfo writeString = typeof(Console).GetMethod("WriteLine",
writeStringArgs);
// Get an ILGenerator and emit a body for the dynamic method,
// using a stream size larger than the IL that will be
// emitted.
ILGenerator il = hello.GetILGenerator(256);
// Load the first argument, which is a string, onto the stack.
il.Emit(OpCodes.Ldarg_0);
// Call the overload of Console.WriteLine that prints a string.
il.EmitCall(OpCodes.Call, writeString, null);
// The Hello method returns the value of the second argument;
// to do this, load the onto the stack and return.
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ret);
// Display MethodAttributes for the dynamic method, set when
// the dynamic method was created.
Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes);
// Display the calling convention of the dynamic method, set when the
// dynamic method was created.
Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention);
// Display the declaring type, which is always null for dynamic
// methods.
if (hello.DeclaringType==null)
{
Console.WriteLine("\r\nDeclaringType is always null for dynamic methods.");
}
else
{
Console.WriteLine("DeclaringType: {0}", hello.DeclaringType);
}
// Display the default value for InitLocals.
if (hello.InitLocals)
{
Console.Write("\r\nThis method contains verifiable code.");
}
else
{
Console.Write("\r\nThis method contains unverifiable code.");
}
Console.WriteLine(" (InitLocals = {0})", hello.InitLocals);
// Display the module specified when the dynamic method was created.
Console.WriteLine("\r\nModule: {0}", hello.Module);
// Display the name specified when the dynamic method was created.
// Note that the name can be blank.
Console.WriteLine("\r\nName: {0}", hello.Name);
// For dynamic methods, the reflected type is always null.
if (hello.ReflectedType==null)
{
Console.WriteLine("\r\nReflectedType is null.");
}
else
{
Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType);
}
if (hello.ReturnParameter==null)
{
Console.WriteLine("\r\nMethod has no return parameter.");
}
else
{
Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter);
}
// If the method has no return type, ReturnType is System.Void.
Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType);
// ReturnTypeCustomAttributes returns an ICustomeAttributeProvider
// that can be used to enumerate the custom attributes of the
// return value. At present, there is no way to set such custom
// attributes, so the list is empty.
if (hello.ReturnType == typeof(void))
{
Console.WriteLine("The method has no return type.");
}
else
{
ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes;
object[] returnAttributes = caProvider.GetCustomAttributes(true);
if (returnAttributes.Length==0)
{
Console.WriteLine("\r\nThe return type has no custom attributes.");
}
else
{
Console.WriteLine("\r\nThe return type has the following custom attributes:");
foreach( object attr in returnAttributes )
{
Console.WriteLine("\t{0}", attr.ToString());
}
}
}
Console.WriteLine("\r\nToString: {0}", hello.ToString());
// Add parameter information to the dynamic method. (This is not
// necessary, but can be useful for debugging.) For each parameter,
// identified by position, supply the parameter attributes and a
// parameter name.
ParameterBuilder parameter1 = hello.DefineParameter(
1,
ParameterAttributes.In,
"message"
);
ParameterBuilder parameter2 = hello.DefineParameter(
2,
ParameterAttributes.In,
"valueToReturn"
);
// Display parameter information.
ParameterInfo[] parameters = hello.GetParameters();
Console.WriteLine("\r\nParameters: name, type, ParameterAttributes");
foreach( ParameterInfo p in parameters )
{
Console.WriteLine("\t{0}, {1}, {2}",
p.Name, p.ParameterType, p.Attributes);
}
// Create a delegate that represents the dynamic method. This
// action completes the method, and any further attempts to
// change the method will cause an exception.
HelloDelegate hi =
(HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate));
// Use the delegate to execute the dynamic method.
Console.WriteLine("\r\nUse the delegate to execute the dynamic method:");
int retval = hi("\r\nHello, World!", 42);
Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42) returned: " + retval);
// Execute it again, with different arguments.
retval = hi("\r\nHi, Mom!", 5280);
Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280) returned: " + retval);
Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:");
// Create an array of arguments to use with the Invoke method.
object[] invokeArgs = {"\r\nHello, World!", 42};
// Invoke the dynamic method using the arguments. This is much
// slower than using the delegate, because you must create an
// array to contain the arguments, and value-type arguments
// must be boxed.
object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us"));
Console.WriteLine("hello.Invoke returned: " + objRet);
}
}
/* This code example produces the following output:
Method Attributes: PrivateScope, Public, Static
Calling convention: Standard
DeclaringType is always null for dynamic methods.
This method contains verifiable code. (InitLocals = True)
Module: CommonLanguageRuntimeLibrary
Name: Hello
ReflectedType is null.
Method has no return parameter.
Return type: System.Int32
The return type has no custom attributes.
ToString: Int32 Hello(System.String, Int32)
Parameters: name, type, ParameterAttributes
message, System.String, In
valueToReturn, System.Int32, In
Use the delegate to execute the dynamic method:
Hello, World!
Invoking delegate hi("Hello, World!", 42) returned: 42
Hi, Mom!
Invoking delegate hi("Hi, Mom!", 5280) returned: 5280
Use the Invoke method to execute the dynamic method:
Hello, World!
hello.Invoke returned: 42
*/
分享到:
相关推荐
Flee(支持.Net Core 2.0) ...使用自定义编译器,轻量级代码生成器和DynamicMethod类将表达式编译为IL 不再使用表达式(以及为其生成的IL)时,将对其进行垃圾回收 不创建任何保留在内存中的动态程序集 以一整
在这个例子中,"com.example.DynamicClass"是你要加载的类,"dynamicMethod"是你想调用的方法,`String.class`是方法的参数类型。 文件“loadClass--反射,动态加载指定类调用类中的方法.txt”可能包含了更具体的...
C#中的动态编译主要依赖于`System.CodeDom.Compiler`命名空间,特别是`CodeDomProvider`类和`CompilerResults`类。`CodeDomProvider`是一个抽象类,它提供了一种方法来生成源代码并将其编译为可执行代码。`...
- `System.Reflection.Emit.DynamicMethod`:这是创建动态方法的主要类。你可以指定方法名、返回类型、参数类型和方法的访问修饰符。 - `System.Reflection.Emit.OpCodes`:这个枚举包含了所有可能的IL指令,如`...
Emit类库是一种在.NET框架中用于动态代码生成的技术,主要通过System.Reflection.Emit命名空间中的类来实现。这个库提供了一种低级别的方法来构建IL(中间语言)指令,允许开发者在运行时创建类型、方法、属性等。...
2. **动态方法(DynamicMethod)**:另一种方法是使用`System.Reflection.Emit`命名空间,创建动态方法来直接操作IL。动态方法允许我们在运行时创建方法,可以直接操作内存,从而达到较高的性能。不过,这种方法需要...
5. **ILGenerator**和`DynamicMethod`:对于更高级的动态组件生成,可以使用`System.Reflection.Emit`命名空间,其中的`ILGenerator`类允许我们直接生成中间语言(IL)代码,而`DynamicMethod`则用于创建和执行这些...
为了实现具有通用类型参数的ReadProcessMemory和WriteProcessMemory,我们可以创建泛型类或泛型方法。泛型方法将允许我们在不牺牲类型安全性的前提下,为各种数据类型提供读写内存的接口。 下面是一个简化的示例,...
C#中,可以使用动态代理(如System.Reflection.Emit命名空间下的DynamicMethod)或者接口实现静态代理,用于添加额外的功能或者控制访问权限。 7. 适配器模式(Adapter Pattern):适配器模式使两个不兼容的接口...
- System.Proxy中的DynamicMethod和Delegate类也可以帮助构建动态代理,用于实现拦截器和AOP。 通过理解并熟练运用代理模式,开发者可以更好地设计和重构系统,提高代码的可维护性和扩展性。在C#中,代理模式的...
Method method = dynamicClass.getMethod("dynamicMethod", ...); method.invoke(instance, ...); ``` 五、注意事项 1. 权限:在AndroidManifest.xml中添加`...
通过`Type`类,我们可以获取到任何类型的信息,而`MethodInfo`类则用于获取和调用方法。例如,我们可以通过字符串参数动态地找到并执行一个方法: ```csharp Type targetType = Type.GetType("MyNamespace.MyClass...
通过`System.Reflection.Emit.DynamicMethod`类,我们可以指定方法名、返回类型、参数列表以及IL(中间语言)代码。IL代码是CLR可理解的指令集,用于构建方法体。例如,我们可以动态创建一个简单的加法函数,如下所...
2. **动态方法调用**:`DynamicQueryable`库的核心是`DynamicMethod`类,它允许在运行时创建并执行方法。`DynamicQueryable`通过解析传入的字符串查询条件,生成对应的`Expression`对象,并最终转换成可执行的Lambda...
return new DynamicMethod(method.Name, method.ReturnType, method.GetParameters().Select(p => p.ParameterType).ToArray(), GetType(), true) { InitLocals = true }.GetILGenerator() .Emit(OpCodes.Ldarg...
在这个实例中,可能通过`DynamicMethod`、`ILGenerator`等类来构建和执行动态生成的IL代码,以实现更高效的对象创建或依赖解析逻辑。 结合反射和Emit,我们可以创建一个高度定制的容器,它不仅能根据配置或元数据...
- 如果可能,使用现有的库或工具,如`DynamicMethod`,它们可能已经处理了一些底层复杂性。 总之,`dynamic-api-caller-dotnet`项目利用`Reflection.Emit`的强大功能,为开发者提供了一种在运行时动态调用Windows ...
4. 动态语言特性:尽管AS3是强类型,但它也具有动态语言的一些特性,如动态属性赋值(`myObject.myDynamicProperty = "value"`)和动态方法调用(`myObject.dynamicMethod()`)。 5. 事件处理:AS3使用事件驱动模型...
例如,可以使用`System.Reflection.Emit`命名空间中的`DynamicMethod`类来创建一个动态方法。 ##### 8. Lambda表达式 Lambda表达式是一种简洁的方式来表示匿名函数。它们通常用于事件处理程序或者传递给某些方法...
需要注意的是要反序列化的类好像必须声明为public的。快速的秘密 大体浏览了一下代码,发现之所以快速的原因是作者利用反射时Emit了大量的IL代码:internal object FastCreateInstance(Type objtype) { ...