VB.NET中的靜態代碼生成技巧。本站提示廣大學習愛好者:(VB.NET中的靜態代碼生成技巧)文章只能為提供參考,不一定能成為您想要的結果。以下是VB.NET中的靜態代碼生成技巧正文
通常,VB.NET順序員會創立一個靜態設計,而這一設計可以為順序的使用提供所需的一切。但是,在某些狀況下,順序員或許不可以事前估計每種需求,這裡就需求用到靜態代碼生成了。
本文的討論也將著眼於這兩種狀況。首先是當順序員需求靜態樹立一個控件並將代碼附著於控件之上時。例如,你或許想創立一個鏈接列表,但是不知道需求創立鏈接的數量或是鏈接中會呈現什麼樣的數據。第二種是當順序員需求定義代碼以反映出特殊需求的時分。例如,你或許要執行能反映用戶零碎配置的代碼。
相似上述的狀況當然不會每天都演出。現實上,它們只在十分狀況下才呈現。但是,作為順序員,依然要認識到.NET為處理靜態情形提供了方案。有了正確的技巧,你就可以寫出能靈敏處置靜態狀況的使用順序了。
運用靜態控件
許多順序員總會遇到需求靜態創立控件的時分。我們所展現的例子中順序員向FlowLayoutPanel中添加了LinkLabels。或許你可以個這樣的設置來記載和保管常用的URL,文件,網絡地址或是其他資源所在地位的數值。這一示例沒有真正保管鏈接,但是你可以運用XML序列化功用來完成保管。
每次當用戶點擊Test按鈕時,示例代碼就會靜態創立一個新的LinkLabel控件。真正的演示代碼並不復雜。例一就展現了創立這類控件以及將控件放入FlowLayoutPanel,lstLabel中通常所需求做的一切。
例一:向FlowLayoutPanel中添加新的鏈接
Private Sub btnTest_Click()
Handles btnTest.Click
' Create a link.
Dim NewLink As LinkLabel =
New LinkLabel()
' Add some properties to it.
NewLink.Text = DateTime.Now
.ToLongTimeString()
' Set the click event handler.
AddHandler NewLink.Click,
AddressOf NewLink_Click
' Place the button on the form.
lstLinks.Controls.Add(NewLink)
End Sub
如你所料,該代碼開端的時分創立了一個新的LinkLabel並為其賦予了一些值。這一示例運用的是以後時間。你的代碼或許可以對某一真實資源停止訪問。
請留意該代碼也向鏈接的Click事情中指定了一個處置順序。你必需運用示例中的AddHandler技巧,由於普通的Handles關鍵詞途徑不起作用。一方面,設計使用順序的時分你並不清楚控件的稱號。即使你為控件指定了一個稱號,你也不知道用戶要創立的控件數量,所以我們沒有方法清楚會有多少處置順序會被創立。處置順序的代碼與控件代碼相似,因而沒有必要創立多個處置順序。用於這個示例的處置代碼見例二。例二:處置靜態控件點擊事情
Private Sub NewLink_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs)
' Verify that you actually have a LinkLabel
If Not sender.GetType() Is GetType(LinkLabel) Then
MessageBox.Show("Wrong control type provided!")
Return
End If
' Convert the input sender to a Button.
Dim ThisLink As LinkLabel = sender
' Show that we have the correct button.
MessageBox.Show("You created this link at: " + ThisLink.Text)
End Sub
你能夠曾經留意到例一中的事情處置器運用的是寬松代表——它沒有將ByVal發送器作為System.Object,也沒有將ByVal e作為System.EventArgs作為參數由於它不需求這二者。但是,當你創立一個事情處置器來靜態創立控件時,通常你需求將ByVal發送器作為System.Object參數,這意味著將這兩者都包括其中。
有些順序員在創立事情處置器的時分會呈現一個錯誤,即沒有反省傳入控件的類型。發送器對象能夠包括多選擇,而假如未對事情處置器停止事情處置類型的設置,那麼你就會面臨更多的選擇。我們的示例代碼一開端就反省了傳入控件對象的類型。這樣以來發送器就不會像上面所展現的代碼一樣:
Private Sub btnTest2_Click() Handles btnTest2.Click
' Create a link.
Dim NewButton As Button = New Button()
' Add some properties to it.
NewButton.Text = DateTime.Now.ToLongTimeString()
' Set the click event handler.
AddHandler NewButton.Click, AddressOf NewLink_Click
' Place the button on the form.
lstLinks.Controls.Add(NewButton)
End Sub
此代碼在FlowLayoutPanel中創立了一個按鈕,大少數狀況下這都能正常運轉,除非事情處置器不依照按鈕所示的停止操作。假如你計劃服務多個控件類型,那麼每個控件類型都需求一個共同的處置。你可以運用多事情處置器或許為某些類型提供選擇規范。
NewLink_Click()事情處置器照常將傳入發送器轉換成指定類型,在這個示例中則是LinkLabel。該代碼可以訪問LinkLabel屬性並能用其他方式停止互動。在我們的示例中,只顯示了一個能在創立鏈接的時分告知我們的對話框。
運用靜態代碼
在運轉時創立一個控件是在無法確定使用順序功用的時分采取的一種戰略。但是靜態創立控件並不適用於一切的狀況。有些時分你必需樹立可執行代碼,雖然你的使用順序運轉的目的是補償不同極端之間的配置,不同用戶的需求,不同的環境需求或是其他要求。當使用順序所運轉的電腦不存在控件,那麼通常是需求創立靜態代碼的。
僥幸的是,.NET為我們提供了一系列靜態代碼選項。例如,你可以創立一個可執行的能獨立運轉的順序或是可以想運轉中的順序加載一個DLL然後再執行。當你需求演示一個內部義務的時分可以運用選擇可執行,如運轉一種腳本——該DLL選項最合適擴展現有的使用順序功用。
你可以運轉來自文件或內存的靜態代碼。當你需求不止一次地運轉代碼時,可以運用文件。對代碼的反省可以再次運轉內部文件而不需求對其停止二次編譯。當你需求屢次演示義務的時分,如一個裝置懇求,那可以運用內存圖像。
當然我們也可以更改源代碼。例如,你可以運用字符串來樹立需求在使用順序中直接運用的代碼。假如你需求代碼具有高度靈敏性,且代碼自身不是很長時,這一辦法的優勢就十分明顯。也可以從文件裡樹立代碼,就好像VS一樣。這一辦法最適用於絕對波動且不需求復雜編碼的需求。第三種選擇是運用Documentation Object Model來創立代碼並將其作為CodeDom樹型構造的一個系列。該樹型構造包括了CodeCormpileUnits。這好像是用DOM形式創立了一個XML文件。
運用靜態創立代碼的最好方式是用示例來反省一下。例三展現了一個根本“Hello World”示例。該示例用源代碼直接創立了代碼因而你可以看到整個運轉以及生成一個內部可執行文件的進程。
例三:靜態編碼示例
Private Sub btnTest3_Click() Handles btnTest3.Click
' Create a compiler.
Dim Comp As VBCodeProvider = New VBCodeProvider()
' Define the parameters for the code you want to compile.
Dim Parms As CompilerParameters = New CompilerParameters)
' We do want to create an executable, rather than a DLL.
Parms.GenerateExecutable = True
' The compiler will create an output assembly called Output.
Parms.OutputAssembly = "Output"
' The compiler won't treat warnings as errors.
Parms.TreatWarningsAsErrors = False
' Add any assembly you want to reference.
Parms.ReferencedAssemblies.Add("System.Windows.Forms.dll")
' Define the code you want to run.
Dim SampleCode As StringBuilder = New StringBuilder()
SampleCode.Append("Imports System.Windows.Forms" + vbCrLf)
SampleCode.Append("Module TestAssembly" + vbCrLf)
SampleCode.Append("Sub Main()" + vbCrLf)
SampleCode.Append("MessageBox.Show(" + Chr(34) + _
"Dynamically Created Code!" + _Chr(34) + ")" + vbCrLf)
SampleCode.Append("End Sub" + vbCrLf)
SampleCode.Append("End Module" + vbCrLf)
' Define the code to run.
Dim Executable As CompilerResults = _
Comp.CompileAssemblyFromSource(Parms, SampleCode.ToString())
' Display error messages if there are any.
If Executable.Errors.HasErrors Then
For Each Item As CompilerError In Executable.Errors
MessageBox.Show(Item.ErrorText)
Next
Else
' If there aren't any error messages, start the
' executable.
Process.Start("Output")
End If
End Sub
一開端你創立了一個運用VBCodeProvider的編譯器Comp。舊一點的.NET版本運用的是不同的辦法但是這裡所講的是微軟引薦的一個新辦法。
為了運用編譯器,你必需創立能描繪使用順序的參數。這些參數相似於VS中你創立的參數,只是如今你可以對它們停止定義。該代碼一開端就將GenerateExecutable設置為True,這意味著你需求的是一個EXE文件而不是DLL。
Parms.OutputAssembly屬性包括了輸入文件的稱號。你只需求在想創立文件時提供這一信息即可,而不需求生成可執行內存了。假如你ixiang生成可執行文件的內存版本,可以將Parm.GenerateInMemory屬性設置為True。
運用Parm.TreatWarningsAsErrors屬性來確定如何處置正告信息。默許的設置會使其為錯誤,這意味著你的使用順序能夠無法對其停止編譯。大少數順序員運用默許設置,雖然他們開發了順序,但是在開發完成的順序中卻將其設置為False。
大少數使用順序需求內部DLL以正常運轉。當然,你不能創立恣意的沒有援用內部DLL的Windows表單順序。通常,你要運用Reference文件夾來完成這一義務。不過,當你靜態創立代碼的時分可以依賴於Parms.ReferencedAssemblies屬性。如下所示,只需添加你要的DLL即可。
如今,你曾經定義了項目,接上去需求為其創立源代碼。如前文所述,你可以依賴於一個內部文件或DOM形式。然後,該示例創立了代碼因而你可以看到整個進程。上面是代碼的原始方式:
Imports System.Windows.Forms
Module TestAssembly
Sub Main()
MessageBox.Show("Dynamically Created Code!")
End Sub
End Module
這個復雜的例子顯示了一個對話框。留意vbCrLf的運用。假如你不運用這一辦法,那編譯器會發送給你一個錯誤信息。vbCrLf條目在該代碼中所起的作用與在順序代碼中的作用相反,只是添加的方式不一樣。
從這一點老說,你最後會用Comp.CompileAsseblyFromSource()辦法編譯代碼。當運用DOM形式和文件的時分可以運用這一辦法。而在一切三種狀況中,編譯器用參數和源代碼創立了你懇求的輸入。該運算的輸入呈現在Executable中,是CompilerResults類型。
編譯的失敗次數多於順序員的估計。無論你是在哪裡運用靜態編碼技巧,你必需假定會呈現失敗的狀況以及處置失敗的方案。在本例中,代碼尋覓的是錯誤並在編譯失敗時將其展現在了信息框中。否則,代碼會依賴於Process.Start()辦法來啟用可執行文件。
底線
靜態編碼技巧並不是萬能鑰匙。當你為開提問題找到了好的靜態處理方案時,當然也可以運用。但是在我們所列出的狀況中沒有可行的靜態方案,因而要選擇靜態編碼技巧。大少數狀況下,要用靜態編碼技巧處理以下問題:
◆ 用戶的環境會以不可預見的方式更改時;
◆ 無法控制用戶電腦的裝置;
◆ 用戶或使用順序都添加了你要用控件執行的數據要素;
◆ 使用順序必需執行很早以前的裝置義務,且這些義務與電腦,環境,網絡或其他不確定要素聯絡嚴密時;
◆ 使用順序要執行了處置級別的義務,且這些義務取決於機器銜接或其他情況。
顯然,還有其他一些狀況能運用靜態編碼技巧。最重要的是記住凡是有不可預知的狀況下要思索運用靜態編碼技巧。通常在編碼環境中呈現了靜態代碼無法處置的狀況時,我們就可以運用靜態編碼技巧。