您的位置:首页 > 其它

反射之人千万不能错过的 EmitHelper

2007-05-07 19:57 495 查看
微软最近貌似要在 SilverLight 和 DLR 上下狠功夫,动态语言的流行和广泛使用的趋势已经是必然,无聊的我浏览了一下DLR的源代码,一堆堆的 ILGenerator.Emit 语句映入眼帘,写过 .NET 语言编译器或者玩过 MSIL 的同学们肯定对这些东西颇为熟悉,如果你恨透了这一行行的 Emit(OpCodes....)... 那你一定要试试 BLToolkit
中的 EmitHelper
以及其他的一些 Reflection 相关的东西,下面的代码使用了 BLToolkit.Reflection.EmitHelper,啊..这才是给人读的代码啊.....

Title

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Reflection;

using System.Reflection.Emit;

using BLToolkit.Reflection;

using BLToolkit.Reflection.Emit;

namespace Adrian.Reflection

{

class Program

{

static void Main(string[] args)

{

string asName = "hw.exe";

AssemblyBuilderHelper assem = new AssemblyBuilderHelper(asName);

TypeBuilderHelper type = assem.DefineType("Emit.Program", TypeAttributes.Public, t.Object);

MethodBuilderHelper add = type.DefineMethod("Add", MethodAttributes.Public | MethodAttributes.Static, t.Int32, new Type[] { t.Int32Array });

add.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "nums");

EmitHelper addIL = add.Emitter;

addIL.DeclareLocal(t.Int32);

addIL.DeclareLocal(t.Int32);

Label cmp = addIL.DefineLabel();

Label end = addIL.DefineLabel();

addIL

.ldc_i4_0

.stloc_0

.ldc_i4_0

.stloc_1

.MarkLabel(cmp)

.ldloc_1

.ldarg_0

.ldlen

.conv_i4

.clt

.brfalse_s(end)

.ldloc_0

.ldarg_0

.ldloc_1

.ldelem_i4

.add

.stloc_0

.ldloc_1

.ldc_i4_1

.add

.stloc_1

.br_s(cmp)

.MarkLabel(end)

.ldloc_0

.ret();

MethodBuilderHelper main = type.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, t.Void, new Type[] { t.StringArray });

main.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "args");

EmitHelper mainIL = main.Emitter;

mainIL.DeclareLocal(t.Int32Array);

mainIL

.ldc_i4_3

.newarr(t.Int32)

.stloc_0

.ldloc_0

.ldc_i4_0

.ldc_i4_1

.stelem_i4

.ldloc_0

.ldc_i4_1

.ldc_i4_2

.stelem_i4

.ldloc_0

.ldc_i4_2

.ldc_i4_3

.stelem_i4

.ldloc_0

.call(add)

.call(typeof(Console), "WriteLine", t.Int32)

.ret();

type.Create();

assem.AssemblyBuilder.SetEntryPoint(main, PEFileKinds.ConsoleApplication);

assem.Save();

Assembly newAs = Assembly.LoadFile(Path.GetFullPath(asName));

newAs.EntryPoint.Invoke(null, new object[] { new string[] { } });

}

}

class t

{

private static Type _int32 = typeof(Int32);

private static Type _int32Array = typeof(Int32[]);

private static Type _object = typeof(Object);

private static Type _void = typeof(void);

private static Type _string = typeof(String);

private static Type _stringArray = typeof(String[]);

public static Type StringArray

{

get { return t._stringArray; }

}

public static Type String

{

get { return t._string; }

}

public static Type Void

{

get { return t._void; }

}

public static Type Object

{

get { return t._object; }

}

public static Type Int32Array

{

get { return t._int32Array; }

}

public static Type Int32

{

get { return _int32; }

}

}

}

中间的那两段 IL 是不是很像Visual C++里的内联汇编?其实 EmitHelper 只是对 ILGenerator 以及所有的 OpCode操作进行了封装,和直接使用 ILGenerator.Emit 是完全等价的, 写起来很有点 Intellisense 的感觉。
废话不说了,BLToolkit 的主页是:http://www.bltoolkit.net/
PS: BLToolkit 是开源的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: