Strongly-typed generic method invokes its argument's base class method, instead of a shadowed method in T?
Consider a MyForm
class that contains a shadowed implementation of Show()
. It also contains a CreateForm()
method, which accepts an instance of the form and calls the shadowed sub:
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)
childFor开发者_如何转开发m.MdiParent = Me
childForm.Show()
childForm.Focus()
End Sub
When called with CreateForm(New MyForm())
, the shadowed implementation of Show()
is correctly called. Now consider the following generic implementation:
Public Sub CreateForm(Of T As Form)(ByVal childForm As T)
childForm.MdiParent = Me
childForm.Show()
childForm.Focus()
End Sub
Called with CreateForm(Of MyForm)(New MyForm())
, this strongly-typed generic method never invokes the shadowed method.
Is this a bug, or am I missing something?
This behavior is "By Design". The trick to remember here is that the generic method is compiled and verified by itself (not in the context of the caller as is done in C++). Hence the generic method only knows that T
is related to Form
. It has no knowledge of MyForm
and hence correctly binds to methods on Form
.
This is correct because Shadows
methods only come into play with the type of the reference at compile time makes the Shadow
method visible. This is not the case here as the reference type at compile type is Form
(not MyForm)
. This is in contrast to Overridable
where the behavior changes based on the runtime type.
You're missing something. It only knows that it is dealing with a Form at compile-time (remember that generics are not templates!). The only thing you can do is use (override) virtual methods instead of shadowing them.
See also 'Shadows' vs. 'Overrides' in VB.NET for more info on shadowing - that's not actually polymorphism.
It's not a bug because the call is evaluated by the compiler statically based just on the given type constraints applied to T
, that is Form
. The compiler cannot predict the actual type could contain a shadowed method declaration or whatever other method not declared in the known parent (i.e. Form
).
精彩评论