【问题标题】:Strongly-typed generic method invokes its argument's base class method, instead of a shadowed method in T?强类型泛型方法调用其参数的基类方法,而不是 T?
【发布时间】:2011-04-27 17:05:39
【问题描述】:

考虑一个包含Show() 的影子实现的MyForm 类。它还包含一个CreateForm() 方法,该方法接受表单的一个实例并调用阴影子:

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()) 调用,这个强类型泛型方法从不调用阴影方法。

这是一个错误,还是我遗漏了什么?

【问题讨论】:

    标签: vb.net generics strong-typing shadowing


    【解决方案1】:

    你错过了一些东西。它只知道它在编译时处理一个表单(请记住,泛型不是模板!)。您唯一能做的就是使用(覆盖)虚拟方法而不是隐藏它们。

    有关阴影的更多信息,另请参阅 'Shadows' vs. 'Overrides' in VB.NET - 这实际上不是多态性。

    【讨论】:

    • 这不是意味着像SomeMethod(Of T)(ByVal arg As T) 这样定义的泛型总是有Object 类型的参数吗?我对泛型方法的调用将类型明确声明为MyForm,因此我认为编译器应该能够推断出参数类型。事实上,这似乎是正常的行为......?
    【解决方案2】:

    这不是错误,因为编译器静态仅根据应用于T(即Form)的给定类型约束来评估调用。编译器无法预测实际类型可能包含阴影方法声明或任何其他未在已知父级中声明的方法(即Form)。

    【讨论】:

      【解决方案3】:

      此行为是“设计使然”。这里要记住的技巧是泛型方法是由自身编译和验证的(而不是在调用者的上下文中,就像在 C++ 中所做的那样)。因此泛型方法只知道TForm 相关。它不知道MyForm,因此正确绑定到Form 上的方法。

      这是正确的,因为Shadows 方法仅在编译时与引用的类型有关,从而使Shadow 方法可见。这不是这里的情况,因为编译类型的引用类型是Form(不是MyForm)。这与Overridable 形成对比,Overridable 的行为根据运行时类型而变化。

      【讨论】:

      • 这是有道理的,但我仍然不明白调用者的上下文如何/为什么与参数类型无关。那不是说像SomeMethod(Of T)(ByVal arg As T) 这样定义的泛型总是有Object 类型的参数吗?
      • @Rob,从arg上的绑定方式来看,是的,本质上认为是Object。这条线在 VB.Net 中有点模糊,尽管默认选项严格是禁用的,并且非对象方法会发生后期绑定。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多