異常處理在程序中也算是比較重要的一部分了,IL異常處理在C#裡面實現會用到一些新的方法
1.BeginExceptionBlock:異常塊代碼開始,相當於try,但是感覺又不太像
2.EndExceptionBlock:異常塊代碼結束,BeginExceptionBlock相當於try,EndExceptionBlock卻不是try結束。而是整個異常塊處理的結束。
3.BeginCatchBlock:catch塊代碼
4.BeginFinallyBlock:finally塊代碼
5.ThrowException:拋出異常
下面我們就通過代碼來實現一下。
一、異常信息捕捉
首先我們做一個簡單的異常捕捉,然後輸出對應的異常信息,首先給出C#代碼:

int translationInt = 0;
try
{
translationInt = Convert.ToInt32(translationStr);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return translationInt;
View Code
實現代碼也比較簡單

string name = "IL4.Dynamic";
string fileName = string.Format("{0}.dll", name);
//構建程序集
AssemblyName assemblyName = new AssemblyName(name);
//應用程序集域
AppDomain domain = AppDomain.CurrentDomain;
//實例化一個AssemblyBuilder對象來實現動態程序集的構建
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
//定義模塊(不加filename為瞬態模塊,不持久)
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name, fileName);
//定義類型
TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);
MethodBuilder methodbuilder = typeBuilder.DefineMethod("ExceptionTest", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(string) });
ILGenerator IL = methodbuilder.GetILGenerator();
LocalBuilder translationInt = IL.DeclareLocal(typeof(Int32));
Type translationException = typeof(Exception);
ConstructorInfo constructorInfo = translationException.GetConstructor(new Type[] { typeof(string) });
MethodInfo exToString = translationException.GetMethod("ToString");
IL.Emit(OpCodes.Ldc_I4_0);
IL.Emit(OpCodes.Stloc_0);
Label tryLabel = IL.BeginExceptionBlock();
IL.Emit(OpCodes.Ldarg_1);
IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
IL.Emit(OpCodes.Stloc_0);
IL.BeginCatchBlock(typeof(Exception));
IL.EmitCall(OpCodes.Callvirt, exToString, null);
IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
IL.EndExceptionBlock();
IL.Emit(OpCodes.Ldloc_0);
IL.Emit(OpCodes.Ret);
View Code
二、拋出異常
程序中有時候,不僅要捕捉異常信息,有時候也是需要拋出對應的異常信息,throw new Exception("translation Exception");這時候就需要用到ThrowException,代碼如下:

IL.Emit(OpCodes.Ldstr, "translation Exception");
IL.Emit(OpCodes.Newobj, constructorInfo);
IL.ThrowException(typeof(newException));
IL.Emit(OpCodes.Ldstr, "20");
IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
IL.Emit(OpCodes.Stloc_0);
IL.EmitCall(OpCodes.Callvirt, exToString, null);
IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
View Code
1.IL.Emit(OpCodes.Newobj, constructorInfo):相當於是一個 new Exception("translation Exception");
2.不過在這一步有一個疑點, IL.ThrowException(typeof(newException));是不會把異常信息"translation Exception"拋出,而在對應的操作IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));卻能輸出這部分的異常信息。可以看下反編譯後的代碼

三、finally處理
finally實現也是比較簡單的,直接上代碼把

IL.BeginFinallyBlock();
IL.Emit(OpCodes.Ldstr, "10");
IL.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) }));
IL.Emit(OpCodes.Stloc_0);
IL.EmitWriteLine("Finally");
IL.EndExceptionBlock();
View Code
異常處理這塊msdn寫得也比較清楚,我也不多說了,示例代碼ExceptionDemo