Sideway
output.to from Sideway
Draft for Information Only

Content

VB.NET Declared Element Shadowing
 Purpose
 Types of Shadowing
  Shadowing Through Scope
  Shadowing Through Inheritance
   Shadowing and Access Level
 Shadowing and Overriding
 Shadowing and Overloading
 Accessing a Shadowed Element
  Declaration of the Object Variable
 See also
  Differences Between Shadowing and Overriding
 Comparison
 Guidelines
 See also
  How to: Hide a Variable with the Same Name as Your Variable
 Two Ways to Hide a Variable
   To hide a variable by shadowing it through scope
   To hide a variable by shadowing it through inheritance
 Robust Programming
 See also
  How to: Hide an Inherited Variable
  To hide an inherited variable
 Robust Programming
 See also
  How to: Access a Variable Hidden by a Derived Class
  To access a base class variable hidden by a derived class
 Robust Programming
 See also
  Source/Reference

VB.NET Declared Element Shadowing

When two programming elements share the same name, one of them can hide, or shadow, the other one. In such a situation, the shadowed element is not available for reference; instead, when your code uses the element name, the Visual Basic compiler resolves it to the shadowing element.

Purpose

The main purpose of shadowing is to protect the definition of your class members. The base class might undergo a change that creates an element with the same name as one you have already defined. If this happens, the Shadows modifier forces references through your class to be resolved to the member you defined, instead of to the new base class element.

Types of Shadowing

An element can shadow another element in two different ways. The shadowing element can be declared inside a subregion of the region containing the shadowed element, in which case the shadowing is accomplished through scope. Or a deriving class can redefine a member of a base class, in which case the shadowing is done through inheritance.

Shadowing Through Scope

It is possible for programming elements in the same module, class, or structure to have the same name but different scope. When two elements are declared in this manner and the code refers to the name they share, the element with the narrower scope shadows the other element (block scope is the narrowest).

For example, a module can define a Public variable named temp, and a procedure within the module can declare a local variable also named temp. References to temp from within the procedure access the local variable, while references to temp from outside the procedure access the Public variable. In this case, the procedure variable temp shadows the module variable temp.

The following illustration shows two variables, both named temp. The local variable temp shadows the member variable temp when accessed from within its own procedure p. However, the MyClass keyword bypasses the shadowing and accesses the member variable.

Graphic that shows shadowing through scope.

For an example of shadowing through scope, see How to: Hide a Variable with the Same Name as Your Variable.

Shadowing Through Inheritance

If a derived class redefines a programming element inherited from a base class, the redefining element shadows the original element. You can shadow any type of declared element, or set of overloaded elements, with any other type. For example, an Integer variable can shadow a Function procedure. If you shadow a procedure with another procedure, you can use a different parameter list and a different return type.

The following illustration shows a base class b and a derived class d that inherits from b. The base class defines a procedure named proc, and the derived class shadows it with another procedure of the same name. The first Call statement accesses the shadowing proc in the derived class. However, the MyBase keyword bypasses the shadowing and accesses the shadowed procedure in the base class.

Graphic diagram of shadowing through inheritance

For an example of shadowing through inheritance, see How to: Hide a Variable with the Same Name as Your Variable and How to: Hide an Inherited Variable.

Shadowing and Access Level

The shadowing element is not always accessible from the code using the derived class. For example, it might be declared Private. In such a case, shadowing is defeated and the compiler resolves any reference to the same element it would have if there had been no shadowing. This element is the accessible element the fewest derivational steps backward from the shadowing class. If the shadowed element is a procedure, the resolution is to the closest accessible version with the same name, parameter list, and return type.

The following example shows an inheritance hierarchy of three classes. Each class defines a Sub procedure display, and each derived class shadows the display procedure in its base class.

Public Class firstClass  
    Public Sub display()  
        MsgBox("This is firstClass")  
    End Sub  
End Class  
Public Class secondClass  
    Inherits firstClass  
    Private Shadows Sub display()  
        MsgBox("This is secondClass")  
    End Sub  
End Class  
Public Class thirdClass  
    Inherits secondClass  
    Public Shadows Sub display()  
        MsgBox("This is thirdClass")  
    End Sub  
End Class  
Module callDisplay  
    Dim first As New firstClass  
    Dim second As New secondClass  
    Dim third As New thirdClass  
    Public Sub callDisplayProcedures()  
        ' The following statement displays "This is firstClass".  
        first.display()  
        ' The following statement displays "This is firstClass".  
        second.display()  
        ' The following statement displays "This is thirdClass".  
        third.display()  
    End Sub  
End Module  

In the preceding example, the derived class secondClass shadows display with a Private procedure. When module callDisplay calls display in secondClass, the calling code is outside secondClass and therefore cannot access the private display procedure. Shadowing is defeated, and the compiler resolves the reference to the base class display procedure.

However, the further derived class thirdClass declares display as Public, so the code in callDisplay can access it.

Shadowing and Overriding

Do not confuse shadowing with overriding. Both are used when a derived class inherits from a base class, and both redefine one declared element with another. But there are significant differences between the two. For a comparison, see Differences Between Shadowing and Overriding.

Shadowing and Overloading

If you shadow the same base class element with more than one element in your derived class, the shadowing elements become overloaded versions of that element. For more information, see Procedure Overloading.

Accessing a Shadowed Element

When you access an element from a derived class, you normally do so through the current instance of that derived class, by qualifying the element name with the Me keyword. If your derived class shadows the element in the base class, you can access the base class element by qualifying it with the MyBase keyword.

For an example of accessing a shadowed element, see How to: Access a Variable Hidden by a Derived Class.

Declaration of the Object Variable

How you create the object variable can also affect whether the derived class accesses a shadowing element or the shadowed element. The following example creates two objects from a derived class, but one object is declared as the base class and the other as the derived class.

Public Class baseCls  
    ' The following statement declares the element that is to be shadowed.  
    Public z As Integer = 100  
End Class  
Public Class dervCls  
    Inherits baseCls  
    ' The following statement declares the shadowing element.  
    Public Shadows z As String = "*"  
End Class  
Public Class useClasses  
    ' The following statement creates the object declared as the base class.  
    Dim basObj As baseCls = New dervCls()  
    ' Note that dervCls widens to its base class baseCls.  
    ' The following statement creates the object declared as the derived class.  
    Dim derObj As dervCls = New dervCls()  
    Public Sub showZ()   
    ' The following statement outputs 100 (the shadowed element).  
        MsgBox("Accessed through base class: " & basObj.z)  
    ' The following statement outputs "*" (the shadowing element).  
        MsgBox("Accessed through derived class: " & derObj.z)  
    End Sub  
End Class  

In the preceding example, the variable basObj is declared as the base class. Assigning a dervCls object to it constitutes a widening conversion and is therefore valid. However, the base class cannot access the shadowing version of the variable z in the derived class, so the compiler resolves basObj.z to the original base class value.

See also

Differences Between Shadowing and Overriding

When you define a class that inherits from a base class, you sometimes want to redefine one or more of the base class elements in the derived class. Shadowing and overriding are both available for this purpose.

Comparison

Shadowing and overriding are both used when a derived class inherits from a base class, and both redefine one declared element with another. But there are significant differences between the two.

The following table compares shadowing with overriding.

Point of comparison Shadowing Overriding
Purpose Protects against a subsequent base-class modification that introduces a member you have already defined in your derived class Achieves polymorphism by defining a different implementation of a procedure or property with the same calling sequence1
Redefined element Any declared element type Only a procedure (Function, Sub, or Operator) or property
Redefining element Any declared element type Only a procedure or property with the identical calling sequence1
Access level of redefining element Any access level Cannot change access level of overridden element
Readability and writability of redefining element Any combination Cannot change readability or writability of overridden property
Control over redefining Base class element cannot enforce or prohibit shadowing Base class element can specify MustOverride, NotOverridable, or Overridable
Keyword usage Shadows recommended in derived class; Shadows assumed if neither Shadows nor Overrides specified2 Overridable or MustOverride required in base class; Overrides required in derived class
Inheritance of redefining element by classes deriving from your derived class Shadowing element inherited by further derived classes; shadowed element still hidden3 Overriding element inherited by further derived classes; overridden element still overridden

1 The calling sequence consists of the element type (Function, Sub, Operator, or Property), name, parameter list, and return type. You cannot override a procedure with a property, or the other way around. You cannot override one kind of procedure (Function, Sub, or Operator) with another kind.

2 If you do not specify either Shadows or Overrides, the compiler issues a warning message to help you be sure which kind of redefinition you want to use. If you ignore the warning, the shadowing mechanism is used.

3 If the shadowing element is inaccessible in a further derived class, shadowing is not inherited. For example, if you declare the shadowing element as Private, a class deriving from your derived class inherits the original element instead of the shadowing element.

Guidelines

You normally use overriding in the following cases:

  • You are defining polymorphic derived classes.

  • You want the safety of having the compiler enforce the identical element type and calling sequence.

You normally use shadowing in the following cases:

  • You anticipate that your base class might be modified and define an element using the same name as yours.

  • You want the freedom of changing the element type or calling sequence.

See also

How to: Hide a Variable with the Same Name as Your Variable

You can hide a variable by shadowing it, that is, by redefining it with a variable of the same name. You can shadow the variable you want to hide in two ways:

  • Shadowing Through Scope. You can shadow it through scope by redeclaring it inside a subregion of the region containing the variable you want to hide.

  • Shadowing Through Inheritance. If the variable you want to hide is defined at class level, you can shadow it through inheritance by redeclaring it with the Shadows keyword in a derived class.

Two Ways to Hide a Variable

To hide a variable by shadowing it through scope

  1. Determine the region defining the variable you want to hide, and determine a subregion in which to redefine it with your variable.

    Variable's region Allowable subregion for redefining it
    Module A class within the module
    Class A subclass within the class

    A procedure within the class

    You cannot redefine a procedure variable in a block within that procedure, for example in an If...End If construction or a For loop.

  2. Create the subregion if it does not already exist.

  3. Within the subregion, write a Dim Statement declaring the shadowing variable.

    When code inside the subregion refers to the variable name, the compiler resolves the reference to the shadowing variable.

    The following example illustrates shadowing through scope, as well as a reference that bypasses the shadowing.

    VB
  1. Module shadowByScope
        ' The following statement declares num as a module-level variable.
        Public num As Integer
        Sub show()
            ' The following statement declares num as a local variable.
            Dim num As Integer
            ' The following statement sets the value of the local variable.
            num = 2
            ' The following statement displays the module-level variable.
            MsgBox(CStr(shadowByScope.num))
        End Sub
        Sub useModuleLevelNum()
            ' The following statement sets the value of the module-level variable.
            num = 1
            show()
        End Sub
    End Module
    

    The preceding example declares the variable num both at module level and at procedure level (in the procedure show). The local variable num shadows the module-level variable num within show, so the local variable is set to 2. However, there is no local variable to shadow num in the useModuleLevelNum procedure. Therefore, useModuleLevelNum sets the value of the module-level variable to 1.

    The MsgBox call inside show bypasses the shadowing mechanism by qualifying num with the module name. Therefore, it displays the module-level variable instead of the local variable.

To hide a variable by shadowing it through inheritance

  1. Be sure the variable you want to hide is declared in a class, and at class level (outside any procedure). Otherwise you cannot shadow it through inheritance.

  2. Define a class derived from the variable's class if one does not already exist.

  3. Inside the derived class, write a Dim statement declaring your variable. Include the Shadows keyword in the declaration.

    When code in the derived class refers to the variable name, the compiler resolves the reference to your variable.

    The following example illustrates shadowing through inheritance. It makes two references, one that accesses the shadowing variable and one that bypasses the shadowing.

    VB
  1. Public Class shadowBaseClass
        Public shadowString As String = "This is the base class string."
    End Class
    Public Class shadowDerivedClass
        Inherits shadowBaseClass
        Public Shadows shadowString As String = "This is the derived class string."
        Public Sub showStrings()
            Dim s As String = "Unqualified shadowString: " & shadowString &
                 vbCrLf & "MyBase.shadowString: " & MyBase.shadowString
            MsgBox(s)
        End Sub
    End Class
    

    The preceding example declares the variable shadowString in the base class and shadows it in the derived class. The procedure showStrings in the derived class displays the shadowing version of the string when the name shadowString is not qualified. It then displays the shadowed version when shadowString is qualified with the MyBase keyword.

Robust Programming

Shadowing introduces more than one version of a variable with the same name. When a code statement refers to the variable name, the version to which the compiler resolves the reference depends on factors such as the location of the code statement and the presence of a qualifying string. This can increase the risk of referring to an unintended version of a shadowed variable. You can lower that risk by fully qualifying all references to a shadowed variable.

See also

How to: Hide an Inherited Variable

A derived class inherits all the definitions of its base class. If you want to define a variable using the same name as an element of the base class, you can hide, or shadow, that base class element when you define your variable in the derived class. If you do this, code in the derived class accesses your variable unless it explicitly bypasses the shadowing mechanism.

Another reason you might want to hide an inherited variable is to protect against base class revision. The base class might undergo a change that alters the element you are inheriting. If this happens, the Shadows modifier forces references from the derived class to be resolved to your variable, instead of to the base class element.

To hide an inherited variable

  1. Be sure the variable you want to hide is declared at class level (outside any procedure). Otherwise you do not need to hide it.

  2. Inside your derived class, write a Dim Statement declaring your variable. Use the same name as that of the inherited variable.

  3. Include the Shadows keyword in the declaration.

    When code in the derived class refers to the variable name, the compiler resolves the reference to your variable.

    The following example illustrates shadowing of an inherited variable.

  1. Public Class shadowBaseClass  
        Public shadowString As String = "This is the base class string."  
    End Class  
    Public Class shadowDerivedClass  
        Inherits shadowBaseClass  
        Public Shadows shadowString As String = "This is the derived class string."  
        Public Sub showStrings()  
            Dim s As String = "Unqualified shadowString: " & shadowString &  
                vbCrLf & "MyBase.shadowString: " & MyBase.shadowString  
            MsgBox(s)  
        End Sub  
    End Class  
    

    The preceding example declares the variable shadowString in the base class and shadows it in the derived class. The procedure showStrings in the derived class displays the shadowing version of the string when the name shadowString is not qualified. It then displays the shadowed version when shadowString is qualified with the MyBase keyword.

Robust Programming

Shadowing introduces more than one version of a variable with the same name. When a code statement refers to the variable name, the version to which the compiler resolves the reference depends on factors such as the location of the code statement and the presence of a qualifying string. This can increase the risk of referring to an unintended version of a shadowed variable. You can lower that risk by fully qualifying all references to a shadowed variable.

See also

How to: Access a Variable Hidden by a Derived Class

When code in a derived class accesses a variable, the compiler normally resolves the reference to the closest accessible version, that is, the accessible version the fewest derivational steps backward from the accessing class. If the variable is defined in the derived class, the code normally accesses that definition.

If the derived class variable shadows a variable in the base class, it hides the base class version. However, you can access the base class variable by qualifying it with the MyBase keyword.

To access a base class variable hidden by a derived class

  • In an expression or assignment statement, precede the variable name with the MyBase keyword and a period (.).

    The compiler resolves the reference to the base class version of the variable.

    The following example illustrates shadowing through inheritance. It makes two references, one that accesses the shadowing variable and one that bypasses the shadowing.

    VB
  • Public Class shadowBaseClass
        Public shadowString As String = "This is the base class string."
    End Class
    Public Class shadowDerivedClass
        Inherits shadowBaseClass
        Public Shadows shadowString As String = "This is the derived class string."
        Public Sub showStrings()
            Dim s As String = "Unqualified shadowString: " & shadowString &
                vbCrLf & "MyBase.shadowString: " & MyBase.shadowString
            MsgBox(s)
        End Sub
    End Class
    

    The preceding example declares the variable shadowString in the base class and shadows it in the derived class. The procedure showStrings in the derived class displays the shadowing version of the string when the name shadowString is not qualified. It then displays the shadowed version when shadowString is qualified with the MyBase keyword.

Robust Programming

To lower the risk of referring to an unintended version of a shadowed variable, you can fully qualify all references to a shadowed variable. Shadowing introduces more than one version of a variable with the same name. When a code statement refers to the variable name, the version to which the compiler resolves the reference depends on factors such as the location of the code statement and the presence of a qualifying string. This can increase the risk of referring to the wrong version of the variable.

See also

 

Source/Reference


©sideway

ID: 200900028 Last Updated: 9/28/2020 Revision: 0 Ref:

close

References

  1. Active Server Pages,  , http://msdn.microsoft.com/en-us/library/aa286483.aspx
  2. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929%28v=vs.90%29.aspx
  3. ASP Best Practices,  , http://technet.microsoft.com/en-us/library/cc939157.aspx
  4. ASP Built-in Objects,  , http://msdn.microsoft.com/en-us/library/ie/ms524716(v=vs.90).aspx
  5. Response Object,  , http://msdn.microsoft.com/en-us/library/ms525405(v=vs.90).aspx
  6. Request Object,  , http://msdn.microsoft.com/en-us/library/ms524948(v=vs.90).aspx
  7. Server Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525541(v=vs.90).aspx
  8. Application Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525360(v=vs.90).aspx
  9. Session Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms524319(8v=vs.90).aspx
  10. ASPError Object,  , http://msdn.microsoft.com/en-us/library/ms524942(v=vs.90).aspx
  11. ObjectContext Object (IIS),  , http://msdn.microsoft.com/en-us/library/ms525667(v=vs.90).aspx
  12. Debugging Global.asa Files,  , http://msdn.microsoft.com/en-us/library/aa291249(v=vs.71).aspx
  13. How to: Debug Global.asa files,  , http://msdn.microsoft.com/en-us/library/ms241868(v=vs.80).aspx
  14. Calling COM Components from ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524620(v=VS.90).aspx
  15. IIS ASP Scripting Reference,  , http://msdn.microsoft.com/en-us/library/ms524664(v=vs.90).aspx
  16. ASP Keywords,  , http://msdn.microsoft.com/en-us/library/ms524672(v=vs.90).aspx
  17. Creating Simple ASP Pages,  , http://msdn.microsoft.com/en-us/library/ms524741(v=vs.90).aspx
  18. Including Files in ASP Applications,  , http://msdn.microsoft.com/en-us/library/ms524876(v=vs.90).aspx
  19. ASP Overview,  , http://msdn.microsoft.com/en-us/library/ms524929(v=vs.90).aspx
  20. FileSystemObject Object,  , http://msdn.microsoft.com/en-us/library/z9ty6h50(v=vs.84).aspx
  21. http://msdn.microsoft.com/en-us/library/windows/desktop/ms675944(v=vs.85).aspx,  , ADO Object Model
  22. ADO Fundamentals,  , http://msdn.microsoft.com/en-us/library/windows/desktop/ms680928(v=vs.85).aspx
close

Latest Updated LinksValid XHTML 1.0 Transitional Valid CSS!Nu Html Checker Firefox53 Chromena IExplorerna
IMAGE

Home 5

Business

Management

HBR 3

Information

Recreation

Hobbies 8

Culture

Chinese 1097

English 339

Reference 79

Computer

Hardware 249

Software

Application 213

Digitization 32

Latex 52

Manim 205

KB 1

Numeric 19

Programming

Web 289

Unicode 504

HTML 66

CSS 65

SVG 46

ASP.NET 270

OS 429

DeskTop 7

Python 72

Knowledge

Mathematics

Formulas 8

Algebra 84

Number Theory 206

Trigonometry 31

Geometry 34

Coordinate Geometry 2

Calculus 67

Complex Analysis 21

Engineering

Tables 8

Mechanical

Mechanics 1

Rigid Bodies

Statics 92

Dynamics 37

Fluid 5

Fluid Kinematics 5

Control

Process Control 1

Acoustics 19

FiniteElement 2

Natural Sciences

Matter 1

Electric 27

Biology 1

Geography 1


Copyright © 2000-2024 Sideway . All rights reserved Disclaimers last modified on 06 September 2019