趣味問題:你能用Reflection.Emit生成這段代碼嗎?
眾所周知,Reflection.Emit是非常強大的工具,可以在運行時動態生成各種程序集、類型和方法的IL代碼,幾乎無所不能。原先我也是這樣認為的,但是看了某個人的博客之后我發現想要用Reflection.Emit做一些特殊的事情還是很需要技巧性的。假設你還沒有看過那個人的博客(暫時先不公開……)可以嘗試一下這個問題。下面的代碼可以用vbc.exe正確編譯(當然等價C#程序也可以經試驗C#編譯器無法處理該邏輯,各位參照VB的行為吧)。。。
Class A
Implements B.I
End Class
Class B
Inherits A
Interface I
End Interface
End Class
Implements B.I
End Class
Class B
Inherits A
Interface I
End Interface
End Class
代碼的邏輯是這樣的,A實現了接口I,而I是B的內嵌類型,B又繼承自A。非常簡單。使用TypeBuilder就可以生成這段邏輯了對吧?不太熟悉Reflection.Emit或者已經忘了怎么開始的朋友可以先參考一下下面的代碼:
Imports System.Reflection
Imports System.Reflection.Emit
Module Program
Sub Main()
Dim name = New AssemblyName("test")
Dim dasm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave)
Dim dmod = dasm.DefineDynamicModule(name.Name, name.Name + ".dll")
Dim tA = dmod.DefineType("A", TypeAttributes.Public Or TypeAttributes.Class)
Dim tB = dmod.DefineType("B", TypeAttributes.Public Or TypeAttributes.Class, tA)
Dim tI = tB.DefineNestedType("I", TypeAttributes.NestedPublic Or TypeAttributes.Interface Or TypeAttributes.Abstract)
tA.AddInterfaceImplementation(tI)
'...
'你需要完成這一部分邏輯,讓test.dll包含剛才的三個類型
'...
dasm.Save(name.Name + ".dll")
End Sub
End Module
Imports System.Reflection.Emit
Module Program
Sub Main()
Dim name = New AssemblyName("test")
Dim dasm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave)
Dim dmod = dasm.DefineDynamicModule(name.Name, name.Name + ".dll")
Dim tA = dmod.DefineType("A", TypeAttributes.Public Or TypeAttributes.Class)
Dim tB = dmod.DefineType("B", TypeAttributes.Public Or TypeAttributes.Class, tA)
Dim tI = tB.DefineNestedType("I", TypeAttributes.NestedPublic Or TypeAttributes.Interface Or TypeAttributes.Abstract)
tA.AddInterfaceImplementation(tI)
'...
'你需要完成這一部分邏輯,讓test.dll包含剛才的三個類型
'...
dasm.Save(name.Name + ".dll")
End Sub
End Module
注釋的地方還沒有寫完,請你補全它,實現上面提到的那三個類型以及正確的關系。
(不需要翻譯成C#了吧,基本上只需要把Dim改成var再加個分號就是C#了……)
老實說我也是剛剛知道了大概的方案,還沒有動手實驗,那就讓我們一起開始動手做一做吧。
全站熱搜