Wednesday, May 2, 2012


VB.NET
Type Members

1 Interface Method Implementation

Methods, events, and properties can implement interface members. To implement an interface member, a member declaration specifies the Implements keyword and lists one or more interface members. Methods and properties that implement interface members are implicitly NotOverridable unless declared to be MustOverride, Overridable, or overriding another member. It is an error for a member implementing an interface member to be Shared. A member's accessibility has no effect on its ability to implement interface members.
For an interface implementation to be valid, the implements list of the containing type must name an interface that contains a compatible member. A compatible member is one whose signature matches the signature of the implementing member. If an event declared using a delegate type is implementing an interface event, then a compatible event is one whose underlying delegate type is the same type. Otherwise, the event uses the delegate type from the interface event it is implementing. If such an event implements multiple interface events, all the interface events must have the same underlying delegate type. For example:
Interface ClickEvents
    Event LeftClick(ByVal x As Integer, ByVal y As Integer)
    Event RightClick(ByVal x As Integer, ByVal y As Integer)
End Interface

Class Button
    Implements ClickEvents

    ' OK. Signatures match, delegate type = ClickEvents.LeftClickHandler.
    Event LeftClick(ByVal x As Integer, ByVal y As Integer) _
        Implements ClickEvents.LeftClick

    ' OK. Signatures match, delegate type = ClickEvents.RightClickHandler.
    Event RightClick(ByVal x As Integer, ByVal y As Integer) _
        Implements ClickEvents.RightClick
End Class

Class Label
    Implements ClickEvents

    ' Error. Signatures match, but can't be both delegate types.
    Event Click(ByVal x As Integer, ByVal y As Integer) _
        Implements ClickEvents.LeftClick, ClickEvents.RightClick
End Class
An interface member in the implements list is specified using a type name, a period, and an identifier. The type name must be an interface in the implements list or a base interface of an interface in the implements list, and the identifier must be a member of the specified interface. A single member can implement more than one matching interface member.
Interface ILeft
    Sub F()
End Interface

Interface IRight
    Sub F()
End Interface

Class Test
    Implements ILeft, IRight

    Sub F() Implements ILeft.F, IRight.F
    End Sub
End Class
If the interface member being implemented is unavailable in all explicitly implemented interfaces because of multiple interface inheritance, the implementing member must explicitly reference a base interface on which the member is available. For example, if I1 and I2 contain a member M, and I3 inherits from I1 and I2, a type implementing I3 will implement I1.M and I2.M. If an interface shadows multiply inherited members, an implementing type will have to implement the inherited members and the member(s) shadowing them.
Interface ILeft
    Sub F()
End Interface

Interface IRight
    Sub F()
End Interface

Interface ILeftRight
    Inherits ILeft, IRight

    Shadows Sub F()
End Interface

Class Test
    Implements ILeftRight

    Sub LeftF() Implements ILeft.F
    End Sub

    Sub RightF() Implements IRight.F
    End Sub

    Sub LeftRightF() Implements ILeftRight.F
    End Sub
End Sub
ImplementsClause ::= [ Implements ImplementsList ]
ImplementsList ::=
   InterfaceMemberSpecifier |
   ImplementsList , InterfaceMemberSpecifier
InterfaceMemberSpecifier ::= TypeName . Identifier

2 Methods

Methods contain the executable statements of a program. Methods, which have an optional list of parameters and an optional return value, are either shared or nonshared. Shared methods are accessed through the class or instances of the class. Nonshared methods, also called instance methods, are accessed through instances of the class. The following example shows a class Stack that has several shared methods (Clone and Flip), and several instance methods (Push,Pop, and ToString):
Imports System
 
Public Class Stack
    Public Shared Function Clone(ByVal s As Stack) As Stack
    End Function
 
    Public Shared Function Flip(ByVal s As Stack) As Stack
    End Function
 
    Public Function Pop() As Object
    End Function
 
    Public Sub Push(ByVal o As Object)
    End Sub 
 
    Public Overrides Function ToString() As String
    End Function 
End Class 
 
Module Test
    Sub Main()
        Dim s As Stack = New Stack()
        Dim i As Integer
 
        While i < 10
            s.Push(i)
        End While
 
        Dim flipped As Stack = Stack.Flip(s)
        Dim cloned As Stack = Stack.Clone(s)
 
        Console.WriteLine("Original stack: " & s.ToString())
        Console.WriteLine("Flipped stack: " & flipped.ToString())
        Console.WriteLine("Cloned stack: " & cloned.ToString())
    End Sub
End Module
Methods can be overloaded, which means that multiple methods may have the same name so long as they have unique signatures. The signature of a method consists of the name of the method and the number and types of its parameters. The signature of a method specifically does not include the return type or parameter modifiers. The following example shows a class with a number of F methods:
Imports System
 
Module Test
    Sub F()
        Console.WriteLine("F()")
    End Sub 
 
    Sub F(ByVal o As Object)
        Console.WriteLine("F(Object)")
    End Sub
 
    Sub F(ByVal value As Integer)
        Console.WriteLine("F(Integer)")
    End Sub 
 
    Sub F(ByVal a As Integer, ByVal b As Integer)
        Console.WriteLine("F(Integer, Integer)")
    End Sub 
 
    Sub F(ByVal values() As Integer)
        Console.WriteLine("F(Integer())")
    End Sub 
 
    Sub Main()
        F()
        F(1)
        F(CType(1, Object))
        F(1, 2)
        F(New Integer() { 1, 2, 3 })
    End Sub
End Module
The output of the program is:
F()
F(Integer)
F(Object)
F(Integer, Integer)
F(Integer())
MethodMemberDeclaration ::= MethodDeclaration | ExternalMethodDeclaration

3 Constructors

Constructors are special methods that allow control over initialization. They are run after the program begins or when an instance of a type is created. Unlike other members, constructors are not inherited and do not introduce a name into a type's declaration space. Constructors may only be invoked by object-creation expressions or by the .NET Framework; they may never be directly invoked.
ConstructorMemberDeclaration ::=
   [ Attributes ] [ ConstructorModifier+ ] Sub New
      [ ( [ ParameterList ] ) ] LineTerminator
   [ Block ]
   End Sub LineTerminator
ConstructorModifier ::= AccessModifier | Shared

4 Events

Events are used to notify code of a particular occurrence. An event declaration consists of an identifier, either a delegate type or a parameter list, and an optional Implements clause. If a delegate type is specified, the delegate type may not have a return type. If a parameter list is specified, it may not contain Optional or ParamArray parameters. The accessibility domain of the parameter types and/or delegate type must be the same as, or a superset of, the accessibility domain of the event itself. Events may be shared by specifying the Shared modifier.
In addition to the member name added to the type's declaration space, an event declaration implicitly declares several other members. Given an event named X, the following members are added to the declaration space:
  • If the form of the declaration is a method declaration, a nested delegate class named XEventHandler is introduced. The nested delegate class matches the method declaration and has the same accessibility as the event. The attributes in the parameter list apply to the parameters of the delegate class.
  • A Private instance variable typed as the delegate, named XEvent.
  • A method named add_X, which takes the delegate type and has the same access type as the event.
  • A method named remove_X, which takes the delegate type and has the same access type as the event.
If a type attempts to declare a name that matches one of the above names, a compile-time error will result. It is not possible to override or overload any of the introduced members, although it is possible to shadow them in derived types. For example, the class declaration
Class Raiser
    Public Event Constructed(ByVal i As Integer)
End Class
is equivalent to the following declaration
Class Raiser
    Public Delegate Sub ConstructedEventHandler(ByVal i As Integer)
 
    Protected ConstructedEvent As ConstructedEventHandler
 
    Public Sub add_Constructed(ByVal d As ConstructedEventHandler)
        ConstructedEvent = _
            CType( _
                ConstructedEvent.Combine(ConstructedEvent, d), _
                    Raiser.ConstructedEventHandler)
    End Sub
 
    Public Sub remove_Constructed(ByVal d As ConstructedEventHandler)
        ConstructedEvent = _
            CType( _
                ConstructedEvent.Remove(ConstructedEvent, d), _
                    Raiser.ConstructedEventHandler)
    End Sub
End Class
Declaring an event without specifying a delegate type is the simplest and most compact syntax, but has the disadvantage of declaring a new delegate type for each event. For example, in the following example, three hidden delegate types are created, even though all three events have the same parameter list:
Public Class Button
    Public Event Click(sender As Object, e As System.EventArgs)
    Public Event DoubleClick(sender As Object, e As System.EventArgs)
    Public Event RightClick(sender As Object, e As System.EventArgs)
End Class
In the following example, the events simply use the same delegate, EventHandler:
Delegate Sub EventHandler(sender As Object, e As System.EventArgs)
Public Class Button
    Public Event Click As EventHandler
    Public Event DoubleClick As EventHandler
    Public Event RightClick As EventHandler
End Class
Events can be handled in one of two ways: statically or dynamically. Statically handling events is simpler and only requires a WithEvents variable and a Handles clause. In the following example, class Form1 statically handles the eventClick of object Button:
Imports System
 
Public Class Form1
    Public WithEvents Button1 As Button = New Button()
    Public Sub Button1_Click(sender As Object, e As System.EventArgs) _
           Handles Button1.Click
        Console.WriteLine("Button1 was clicked!")
    End Sub
End Class
Dynamically handling events is more complex because the event must be explicitly connected and disconnected to in code. The statement AddHandler adds a handler for an event, and the statement RemoveHandler removes a handler for an event. The next example shows a class Form1 that adds Button1_Click as an event handler for Button1's Clickevent:
Imports System
 
Public Class Form1
    Public Sub New()
        ' Add Button1_Click as an event handler for Button1's Click event.
        AddHandler Button1.Click , AddressOf Button1_Click
    End Sub 
 
    Private Button1 As Button = New Button()
 
    Sub Button1_Click(sender As Object, e As EventArgs)
        Console.WriteLine("Button1 was clicked!")
    End Sub
 
    Public Sub Disconnect()
        RemoveHandler Button1.Click, AddressOf Button1_Click
    End Sub 
End Class 
In method Disconnect, the event handler is removed.
EventMemberDeclaration ::=
   [ Attributes ] [ EventModifiers+ ] Event Identifier ParametersOrType
      [ ImplementsClause ] LineTerminator
ParametersOrType ::=
   [ ( [ ParameterList ] ) ] |
   As TypeName
EventModifiers ::= AccessModifier | Shadows | Shared

 

5 Constants

A constant is a constant value that is a member of a type. Constants are implicitly shared. If the declaration contains anAs clause, the clause specifies the type of the member introduced by the declaration. If the type is omitted and strict semantics are being used, a compile-time error occurs; otherwise the type of the constant is implicitly Object. The type of a constant may only be a primitive type or Object. If a constant is typed as Object and there is no type character, the real type of the constant will be the type of the constant expression. Otherwise, the type of the constant is the type of the constant's type character.
The following example shows a class named Constants that has two public constants:
Class Constants
    Public A As Integer = 1
    Public B As Integer = A + 1
End Class 
Constants can be accessed through the class, as in the following example, which prints out the values of Constants.Aand Constants.B.
Module Test
    Sub Main()
        Console.WriteLine(Constants.A & ", " & Constants.B)
    End Sub 
End Module
A constant declaration that declares multiple constants is equivalent to multiple declarations of single constants. The following example declares three constants in one declaration statement.
Class A
    Protected Const x As Integer = 1, y As Long = 2, z As Short = 3
End Class
This declaration is equivalent to the following:
Class A
    Protected Const x As Integer = 1
    Protected Const y As Long = 2
    Protected Const z As Short = 3
End Class
The accessibility domain of the type of the constant must be the same as or a superset of the accessibility domain of the constant itself. The constant expression must yield a value of the constant's type or of a type that is implicitly convertible to the constant's type. The constant expression may not be circular; that is, a constant may not be defined in terms of itself.
The compiler automatically evaluates the constant declarations in the appropriate order. In the following example, the compiler first evaluates Y, then Z, and finally X, producing the values 10, 11, and 12, respectively.
Class A
    Public Const X As Integer = B.Z + 1
    Public Const Y As Integer = 10
End Class
 
Class B
    Public Const Z As Integer = A.Y + 1
End Class
When a symbolic name for a constant value is desired, but the type of the value is not permitted in a constant declaration or when the value cannot be computed at compile time by a constant expression, a read-only variable may be used instead.
ConstantMemberDeclaration ::=
   [ Attributes ] [ ConstantModifier+ ] Const
      ConstantDeclarators LineTerminator
ConstantModifier ::= AccessModifier | Shadows
ConstantDeclarators ::= 
   ConstantDeclarator |
   ConstantDeclarators , ConstantDeclarator
ConstantDeclarator ::= Identifier [ As TypeName ] =
   ConstantExpression LineTerminator

 

6 Instance and Shared Variables

An instance or shared variable is a member of a type that can store information. The Dim modifier must be specified if no modifiers are specified, but may be omitted otherwise. A single variable declaration may include multiple variable declarators; each variable declarator introduces a new instance or shared member. If an initializer is specified, only one instance or shared variable may be declared by the variable declarator.
A variable declared with the Shared modifier is a shared variable. A shared variable identifies exactly one storage location regardless of the number of instances of the type that are created. A shared variable comes into existence when a program begins executing, and ceases to exist when the program terminates.
A variable declared without the Shared modifier is called an instance variable. Every instance of a class contains a separate copy of all instance variables of the class. An instance variable of a reference type comes into existence when a new instance of that type is created, and ceases to exist when there are no references to that instance and theFinalize method has executed. An instance variable of a value type has exactly the same lifetime as the variable to which it belongs. In other words, when a variable of a value type comes into existence or ceases to exist, so does the instance variable of the value type.
If the declarator contains an As clause, the clause specifies the type of the members introduced by the declaration. If the type is omitted and strict semantics are being used, a compile-time error occurs. Otherwise the type of the members is implicitly Object or the type of the members' type character.
Note   There is no ambiguity in the syntax: if a declarator omits a type, it will always use the type of a following declarator.
The accessibility domain of an instance or shared variable's type or array element type must be the same as or a superset of the accessibility domain of the instance or shared variable itself.
The following example shows a Color class that has internal instance variables named redPart, greenPart, andbluePart:
Class Color
    Friend redPart As Short
    Friend bluePart As Short
    Friend greenPart As Short
 
    Public Sub New(red As Short, blue As Short, green As Short)
        redPart = red
        bluePart = blue
        greenPart = green
    End Sub
End Class
VariableMemberDeclaration ::=
   [ Attributes ] [ VariableModifier+ ] [ Dim ] VariableDeclarators
      LineTerminator
VariableModifier ::=
   AccessModifier |
   Shadows |
   Shared |
   ReadOnly |
   WithEvents
VariableDeclarators ::=
   VariableDeclarator |
   VariableDeclarators , VariableDeclarator
VariableDeclarator ::=
   VariableIdentifiers [ As TypeName ] |
   VariableIdentifier [ As [ New ] TypeName [ ( ArgumentList ) ] ]
      [ = VariableInitializer ]
VariableIdentifiers ::=
   VariableIdentifier |
   VariableIdentifiers , VariableIdentifier
VariableIdentifier ::= Identifier [ ArrayNameModifier ]

 

7 Properties

Properties are a natural extension of variables; both are named members with associated types, and the syntax for accessing variables and properties is the same. Unlike variables, however, properties do not denote storage locations. Instead, properties have accessors, which specify the statements to execute in order to read or write their values.
Properties are defined with property declarations. The first part of a property declaration resembles a field declaration. The second part includes a Get accessor and/or a Set accessor. In the example below, the Button class defines aCaption property.
Public Class Button
    Private captionValue As String
 
    Public Property Caption() As String
        Get
            Return captionValue
        End Get
 
        Set (ByVal Value As String)
            captionValue = value
            Repaint()
        End Set
    End Property
End Class
Based on the Button class above, the following is an example of use of the Caption property:
Dim okButton As Button = New Button()
 
okButton.Caption = "OK" ' Invokes Set accessor.
Dim s As String = okButton.Caption ' Invokes Get accessor.
Here, the Set accessor is invoked by assigning a value to the property, and the Get accessor is invoked by referencing the property in an expression.
If no type is specified for a property and strict semantics are being used, a compile-time error occurs; otherwise the type of the property is implicitly Object or the type of the property's type character. A property declaration may contain either a Get accessor, which retrieves the value of the property, a Set accessor, which stores the value of the property, or both. Because a property implicitly declares methods, a property may be declared with the same modifiers as a method. If the property is defined in an interface or defined with the MustOverride modifier, the property body and theEnd construct must be omitted; otherwise, a compile-time error occurs.
The index parameter list makes up the signature of the property, so properties may be overloaded on index parameters but not on the type of the property. The index parameter list is the same as for a regular method. However, none of the parameters may be modified with the ByRef modifier and none of them may be named Value (which is reserved for the implicit value parameter in the Set accessor).
A property may be declared as follows:
  • If the property specifies no property type modifier, the property must have both a Get accessor and a Setaccessor. The property is said to be a read-write property.
  • If the property specifies the ReadOnly modifier, the property must have a Get accessor and may not have a Setaccessor. The property is said to be read-only property. It is a compile-time error for a read-only property to be the target of an assignment.
  • If the property specifies the WriteOnly modifier, the property must have a Set accessor and may not have a Getaccessor. The property is said to be write-only property. It is a compile-time error to reference a write-only property in an expression except as the target of an assignment or as an argument to a method.
The Get and Set accessors of a property are not distinct members, and it is not possible to declare the accessors of a property separately. The following example does not declare a single read-write property. Rather, it declares two properties with the same name, one read-only and one write-only:
Class A
    Private nameValue As String
 
    ' Error, contains a duplicate member name.
    Public ReadOnly Property Name() As String 
        Get
            Return nameValue
        End Get
    End Property
 
    ' Error, contains a duplicate member name.
    Public WriteOnly Property Name() As String 
        Set (ByVal Value As String)
            nameValue = value
        End Set
    End Property
End Class
Since two members declared in the same class cannot have the same name, the example causes a compile-time error.
When a derived type shadows a property, the derived property hides the shadowed property with respect to both reading and writing. In the following example, the P property in B hides the P property in A with respect to both reading and writing:
Class A
    Public WriteOnly Property P() As Integer
        Set (ByVal Value As Integer)
        End Set
    End Property
End Class
 
Class B
    Inherits A
 
    Public Shadows ReadOnly Property P() As Integer
       Get
       End Get
    End Property
End Class
 
Module Test
    Sub Main()
        Dim x As B = New B
 
        B.P = 10     ' Error, B.P is read-only.
    End Sub
End Module
The accessibility domain of the return type or parameter types must be the same as or a superset of the accessibility domain of the property itself. A property may only have one Set accessor and one Get accessor.
Except for differences in declaration and invocation syntax, Overridable, NotOverridable, Overrides, MustOverride, and MustInherit properties behave exactly like Overridable, NotOverridable, Overrides, MustOverride, andMustInherit methods. When a property is overridden, the overriding property must be of the same type (read-write, read-only, write-only).
In the following example X is an Overridable read-only property, Y is an Overridable read-write property, and Z is aMustOverride read-write property.
MustInherit Class A
    Private y As Integer
 
    Public Overridable ReadOnly Property X() As Integer
        Get
            Return 0
        End Get
    End Property
 
    Public Overridable Property Y() As Integer
        Get
            Return y
         End Get
        Set (ByVal Value As Integer)
            y = value
        End Set
    End Property
 
    Public MustOverride Property Z() As Integer
End Class
Because Z is MustOverride, the containing class A must be declared MustInherit.
By contrast, a class that derives from class A is shown below:
Class B
    Inherits A
 
    Private zValue As Integer
 
    Public Overrides ReadOnly Property X() As Integer
        Get
            Return MyBase.X + 1
        End Get
    End Property
 
    Public Overrides Property Y() As Integer
        Get
            Return MyBase.Y
        End Get
        Set (ByVal Value As Integer)
            If value < 0 Then
                MyBase.Y = 0
            Else
                MyBase.Y = Value
            End If
        End Set
    End Property
 
    Public Overrides Property Z() As Integer
        Get
            Return zValue
        End Get
        Set (ByVal Value As Integer)
            zValue = Value
        End Set
    End Property
End Class 
Here, the declarations of properties X, Y, and Z override the base properties. Each property declaration exactly matches the accessibility modifiers, type, and name of the corresponding inherited property. The Get accessor of property X and the Set accessor of property Y use the MyBase keyword to access the inherited properties. The declaration of property Z overrides the MustOverride property — thus, there are no outstanding MustOverridemembers in class B, and B is permitted to be a regular class.
Properties can be used to delay initialization of a resource until the moment it is first referenced. For example:
Imports System.IO
 
Public Class ConsoleStreams
    Private Shared reader As TextReader
    Private Shared writer As TextWriter
    Private Shared errors As TextWriter
 
    Public Shared ReadOnly Property [In]() As TextReader
        Get
            If reader Is Nothing Then
                reader = New StreamReader(File.OpenStandardInput())
            End If
            Return reader
        End Get
    End Property
 
    Public Shared ReadOnly Property Out() As TextWriter
        Get
            If writer Is Nothing Then
                writer = New StreamWriter(File.OpenStandardOutput())
            End If
            Return writer
        End Get
    End Property
 
    Public Shared ReadOnly Property [Error]() As TextWriter
        Get
            If errors Is Nothing Then
                errors = New StreamWriter(File.OpenStandardError())
            End If
            Return errors
        End Get
    End Property
End Class
The ConsoleStreams class contains three properties, In, Out, and Error, that represent the standard input, output, and error devices, respectively. By exposing these members as properties, the ConsoleStreams class can delay their initialization until they are actually used. For example, upon first referencing the Out property, as inConsoleStreams.Out.WriteLine("hello, world"), the underlying TextWriter for the output device is created. But if the application makes no reference to the In and Error properties, then no objects are created for those devices.
PropertyMemberDeclaration ::=
   [ Attributes ] [ PropertyModifier+ ] Property Identifier
      [ ( [ ParameterList ] ) ] [ As TypeName ] [ ImplementsClause ]
      LineTerminator
   [ PropertyAccessorDeclaration+ ]
   [ End Property LineTerminator ]
PropertyModifier ::= ProcedureModifier | Default | ReadOnly | WriteOnly
PropertyAccessorDeclaration ::=
   PropertyGetDeclaration | 
   PropertySetDeclaration

Objects, Properties, Methods, and Events

Objects, properties, methods, and events are the basic units of object-oriented programming. An object is an element of an application, representing an instance of a class. Properties, methods, and events are the building blocks of objects, and constitute their members.

Objects

An object represents an instance of a class such as Form, Control, or Component. In Visual Basic code, you mustinstantiate an object before you can apply one of the object's methods or change the value of one of its properties. Instantiation is the process by which an instance of a class is created and assigned to an object variable. An example is shown below:
Dim x As New MyClass()
In this example, the variable x is assigned to refer to a new instance of the class MyClass.

Properties

A property is an attribute of an object that defines one of the object's characteristics, such as size, color, or screen location, or an aspect of its behavior, such as whether it is enabled or visible. To change the characteristics of an object, you change the values of its corresponding properties.
To set the value of a property, affix the reference to an object with a period, the property name, an equal sign (=), and the new property value. For example, the following procedure changes the caption of a Visual Basic Windows Form by setting the Text property:
Public Sub ChangeName(newTitle)
   myForm.Text = newTitle
End Sub
You can't set some properties. The Help topic for each property indicates whether you can set that property (read/write), only read the property (read-only), or only write the property (write-only).
You can retrieve information about an object by returning the value of one of its properties. The following procedure uses a message box to display the title that appears at the top of the currently active form.
Public Sub GetFormName()
   Dim formName As String
   formName = myForm.Text
   MsgBox(formName)
End Sub

Methods

A method is an action that an object can perform. For example, Add is a method of the ComboBox object, because it adds a new entry to a combo box.
The following example demonstrates the Start method of a Timer component:
' Instantiates a Timer object.
Dim myTimer As New System.Windows.Forms.Timer()   
' Invokes the Start method of myTimer.
MyTimer.Start

Events

An event is an action recognized by an object, such as clicking the mouse or pressing a key, and for which you can write code to respond. Events can occur as a result of a user action or program code, or they can be triggered by the system. You can also develop your own custom events to be raised by your objects and handled by other objects. For further information, see Events and Delegates.

 




No comments:

Post a Comment