2010-10-19 73 views
3

考慮一個MyForm類,其中包含Show()的影子實現。它還包含一個CreateForm()方法,它接受的形式的一個實例,並調用陰影子:強類型泛型方法調用其參數的基類方法,而不是T中的陰影方法?

Public Class MyForm 
    Inherits Form 

    Public Shadows Sub Show() 
     MessageBox.Show("Shadowed implementation called!") 
    End Sub 
End Class 

... 

Public Sub CreateForm(ByVal childForm As MyForm) 
    childForm.MdiParent = Me 
    childForm.Show() 
    childForm.Focus() 
End Sub 

當與CreateForm(New MyForm())調用的Show()陰影實現正確調用。現在考慮下面的通用實現:

Public Sub CreateForm(Of T As Form)(ByVal childForm As T) 
    childForm.MdiParent = Me 
    childForm.Show() 
    childForm.Focus() 
End Sub 

CreateForm(Of MyForm)(New MyForm())調用,這個強類型的泛型方法從未調用陰影方法。

這是一個錯誤,還是我錯過了什麼?

回答

3

此行爲是「按設計」。這裏要記住的技巧是泛型方法是由自己編譯和驗證的(不像在C++中那樣在調用者的上下文中)。因此,通用方法只知道TForm有關。它不知道MyForm,因此正確地綁定到Form上的方法。

這是正確的,因爲Shadows方法只在編譯時引用類型的引用使Shadow方法可見。這不是這種情況,因爲編譯類型的引用類型是Form(不是MyForm)。這與Overridable相反,其中行爲根據運行時類型而改變。

+0

這是有道理的,但我仍然不知道如何/爲什麼調用者的上下文沒有關係的參數類型。那不就是說像'SomeMethod(Of T)(ByVal arg As T)'這樣的泛型定義總是會有一個Object類型的參數嗎? – Rob 2010-10-19 20:50:18

+0

@Rob,從'arg'綁定方法的角度來看,是的,它本質上被認爲是'Object'。這行在VB.Net中有點模糊,但默認情況下選項strict被禁用,並且非對象方法會發生後期綁定。 – JaredPar 2010-10-19 20:55:49

2

你錯過了什麼。它只知道它是在編譯時處理一個表單(記住泛型不是模板!)。你可以做的唯一事情就是使用(覆蓋)虛擬方法,而不是對它們進行遮蔽。

另請參閱'Shadows' vs. 'Overrides' in VB.NET有關陰影的更多信息 - 實際上並非多態。

+0

這不是說泛型定義類似於'SomeMethod (Of T)(ByVal arg As T)'總是有一個類型爲'Object'的參數?我對泛型方法的調用明確指出類型爲'MyForm',所以我認爲編譯器應該能夠推斷參數類型事實上,這似乎是正常的行爲...? – Rob 2010-10-19 20:54:40

+0

沒關係,我現在明白了:) – Rob 2010-10-19 21:17:08

1

,因爲呼叫是通過僅僅基於應用到T給定類型的約束編譯器靜態評價這是不是一個錯誤,那就是Form。編譯器無法預測實際類型可能包含陰影方法聲明或任何未在已知父項中聲明的其他方法(即Form)。

相關問題