2015-09-10 41 views
1

我正在將VB6項目轉換爲Vb.net。將表格作爲參考並將其稱爲公共子

我有10+的形式,所有有這樣的子:

Public sub DoSomething() 
    *doing stuff here 
end sub 

而且我那叫一個主要形式的其它形式的子

private sub TouchForm(frmRef as form) 
    dim FormPublic as Form 
    set FormPublic = frmRef 
    FormPublic.Show 
    FormPublic.DoSomething() 
End Sub 

我對FormPublic得到一個錯誤.DoSomething()不是「System.Windows.Forms.Form」的成員,當我嘗試在Vb.net中執行此操作時。

+1

這是因爲'DoSomething的()'是在一個特定的類,它是不是'System.Windows.Forms.Form'的功能。你必須用正確的類名稱在'dim FormPublic as Form'中替換'Form'類型。如果它們都具有這種格式,爲什麼不讓它們在指定該函數的地方實現'interface',以便您可以在實現您的接口的所有窗體上調用該方法? –

+0

我無法用FormPublic替換窗體,因爲frmRef已經是用作參數的窗體。我有另一個代碼選擇選擇哪種形式,然後在TouchForm中使用該形式作爲參數 – user3444498

+0

這隻能在Option Strict Off有效的情況下編譯。在VB6項目中不太可能。 「適當的」方法是聲明所有這些表單都實現的接口。 –

回答

3

在.NET中,編譯器檢查變量類型以確保您只調用實際存在的成員。這種類型檢查是許多人喜歡的編譯時安全功能,因爲它避免了由於意外使用不受支持的成員而導致的不必要的運行時錯誤。

但是,爲了使VB.NET儘可能與VB6向後兼容,Microsoft添加了一個新選項。就像VB6有Option Explicit允許它向後兼容不需要變量聲明的舊版本,VB.NET增加了一個新的Option Strict

當您打開Option Strict Off時,它將禁用該編譯器類型檢查功能,以便允許使用VB6風格的後期綁定。但是,這並不完美。即使使用Option Strict Off,只有在Object類型的變量上才允許延遲綁定語法。因此,爲了呼叫未經檢查的成員,您需要先將對象轉換爲Object類型。例如:

Option Strict Off 

Private Sub TouchForm(frmRef As form) 
    Dim FormPublic As Object 
    FormPublic = frmRef 
    FormPublic.Show 
    FormPublic.DoSomething() 
End Sub 

或者更簡單地說:

Option Strict Off 

Private Sub TouchForm(frmRef As Object) 
    frmRef.Show 
    frmRef.DoSomething() 
End Sub 

然而,正如馬克西米利安在上面的評論說,在大多數情況下,最好是離開Option Strict On,這樣就可以保留有價值的類型 - 檢查。正如他所提到的,最明顯的方式做到這一點,同時仍保持Option Strict On,是讓所有的形式實現共同的接口,這樣的:

Public Interface ISomeInterface 
    Sub Show() 
    Sub DoSomething() 
End Interface 

Private Sub TouchForm(frmRef As ISomeInterface) 
    frmRef.Show 
    frmRef.DoSomething() 
End Sub 

當你這樣做的,編譯器只將如果您傳入實現該特定接口的對象,則允許您調用TouchForm方法。因此,您需要在支持這些功能的所有Form類中實現該接口。如果你試圖調用它並將它傳遞給一個沒有實現該接口的表單,它將無法編譯。

如果接口不合適,用於完成同樣事情的其他選項將是使用基類或委託。如果沒有這些事情都是可能的,你必須把它叫做後期綁定,但你還是要離開Option Strict On,你仍然可以做到這一點通過使用反射的:

Private Sub TouchForm(frmRef As Form) 
    frmRef.Show 
    frmRef..GetType().GetMethod("DoSomething").Invoke(frmRef, {}) 
End Sub 

談到Option Strict Off不總是一個不好的選擇。這是一個非常有用的功能,它實際上是通過它的dynamic關鍵字添加到C#中的。但是,在VB中,沒有辦法在逐個變量的基礎上進行,所以它不夠靈活。在VB中,您只能爲整個文件打開Option Strict Off。所以當你這樣做的時候,那個文件中的代碼都沒有進行類型檢查。所以,在我看來,如果你確實關閉了,最好儘可能少地保存文件,並儘可能縮短文件的長度。您甚至可以考慮將其實現爲Partial Class,以便只有該類的一個方法處於未經檢查的文件中,而其餘的代碼位於另一個經過類型檢查的文件中。

+0

謝謝你們!我使用了Interface。學到的新知識。 – user3444498

0

你必須嘗試這樣的事:

private sub TouchForm(frmRef as form) 
     dim FormPublic as Form = New frmRef 
     FormPublic.Show 
     FormPublic.DoSomething() 
End Sub 
+0

在你的例子中,'frmRef'是一個變量名,而不是一個類型。除非'frmRef'也是一個類型的名字,否則這些代碼將不會被編譯。儘管如此,代碼沒有任何意義。由於它將在方法內部創建一個新的'frmRef'對象,所以'frmRef'參數永遠不會被使用,而且完全沒有必要。既然我們可以假設OP有包含該參數的充分理由,那麼您的解決方案就不太可能有幫助,因爲它會改變方法的結果/目的。 –

+0

此外,它並沒有解決原來的問題。 「FormPublic」變量仍然被鍵入爲「Form」,所以「DoSomething」仍然不是該類型的成員,並且不能被調用。 –

相關問題