由于阴影,我关键字无法在派生类中执行子例程

Sou*_*ata 1 vb.net

我在理解ShadowsMe. 下面是我写的代码:

Module Module1
    Sub main()
        Dim c As New Customer()
        c.UseMe() 'See item 1 
        Console.WriteLine("----")
        c.DoSomething()
        Console.ReadLine()
    End Sub
End Module

Public Class Person
    Public Sub DoSomething()
        Console.WriteLine("Person")
    End Sub

    Public Sub UseMe()
        Me.DoSomething() 'See item 2
        'See item 3
    End Sub
End Class

Public Class Customer
    Inherits Person

    Public Shadows Sub DoSomething()
        'See item 4
        Console.WriteLine("Customer")
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

以下是我期望它的工作方式(但它没有):

  1. c是派生类的对象,但调用类中的UseMe方法Person
  2. Me关键字表现得像一个对象指的是当前实例(在这种情况下是c
  3. 因此Me.DoSomething = c.DoSomething,控制权应该转移到派生类
  4. 一旦控制转移到派生类,编译器就应该DoSomething在派生类中执行 ,因为它隐藏DoSomething了基类中的 。因此输出应该是"Customer"。但输出是“人”

你能解释一下我的理解哪里出了问题吗?我想知道为什么Shadows阻止 Me.DoSomething()执行DoSomething派生类中的方法,而是执行基类中的方法。

jmc*_*ney 5

ShadowsOverrides除了前者总是作用于引用的类型而后者总是作用于对象的类型之外,与此类似。考虑以下代码:

Module Module1

    Sub Main()
        Dim b1 As New Base
        Dim d As New Derived
        Dim b2 As Base = DirectCast(d, Base)

        b1.OverrideTest()
        b1.ShadowTest()
        d.OverrideTest()
        d.ShadowTest()
        b2.OverrideTest()
        b2.ShadowTest()

        Console.ReadLine()
    End Sub

End Module


Public Class Base

    Public Overridable Sub OverrideTest()
        Console.WriteLine("Base.OverrideTest")
    End Sub

    Public Sub ShadowTest()
        Console.WriteLine("Base.ShadowTest")
    End Sub

End Class


Public Class Derived
    Inherits Base

    Public Overrides Sub OverrideTest()
        Console.WriteLine("Derived.OverrideTest")
    End Sub

    Public Shadows Sub ShadowTest()
        Console.WriteLine("Derived.ShadowTest")
    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

这段代码的输出如下:

Base.OverrideTest
Base.ShadowTest
Derived.OverrideTest
派生阴影测试
Derived.OverrideTest
Base.ShadowTest

因此,当使用BaseBase对象的引用时,两种方法都会调用基本实现。不出意外。当使用DerivedDerived对象的引用时,两种方法都会调用派生的实现。也不奇怪。另一方面,当使用BaseDerived对象的引用时,被覆盖的方法调用派生的实现,即对对象的类型起作用,而被遮蔽的方法调用基实现,即对引用的类型起作用。

在您的代码中,您MePerson类中使用。Me显然是对当前对象的引用,但它只能是当前类型的引用,即代码实际所在的类型。您使用的代码Me在基类型中,因此它将始终调用隐藏成员的基实现。