MORE INFORMATION
Microsoft .NET includes two kinds of data types:
- Value types. Types that are allocated in a stack or inline in a
structure.
- Reference types. Types that are allocated in a heap.
Both value types and reference types are derived from the base
class,
System.Object.
When you need a value type to behave like an object, a
wrapper that makes the value type look like a reference object is allocated on
the heap. Subsequently, the value of the value type is copied into the wrapper.
The wrapper is marked so that the system knows that the wrapper contains a
value type. This process is known as boxing, and the reverse process is known
as unboxing. Boxing and unboxing allow any type to be treated as an
object.
Value Types
Value types store the data directly on the stack. You can access
this data directly. To create a copy of the value that is assigned, you can
assign a value type to a variable. Value types are not inheritable. They are
implicitly derived from the
System.ValueType class, which derives from
System.Object.
Value types include primitives, enumerators, and
structures.
Primitives
Primitives are the foundation of data types. Primitives are the
lowest types available. You can identify primitives through keywords, which are
aliases for predefined types in the
System namespace. For example, in Visual Basic 2005 and in Visual Basic .NET, the
Integer data type is an alias for the
System.Int32 object.
Because all data types are derived from
System.Object, primitives are actually objects with a set of members that are
available for each type. For example, the
Integer data type has a member named
MaxValue.
Visual Basic 2005 and Visual Basic .NET define the following primitive
types:
|
Byte | System.Byte | 1 byte unsigned integer | 0 |
Short | System.Int16 | 2 byte signed integer | 0 |
Integer | System.Int32 | 4 byte signed integer | 0 |
Long | System.Int64 | 8 byte signed integer | 0 |
Single | System.Single | 4 byte floating point | 0 |
Double | System.Double | 8 byte floating point | 0 |
Decimal | System.Decimal | 16 byte decimal | 0D |
Boolean | System.Boolean | True or False | False |
Date | System.DateTime | Date time stamp | #01/01/0001 12:00:00 AM# |
Char | System.Char | Single unicode character | ChrW(0) |
String | System.String | Multiple unicode characters | null reference |
Of these primitive types, only the
String type is a reference type. All of the other primitive types are
value types.
The following list outlines some of the differences
between data types in Visual Basic 2005, in Visual Basic .NET, and in Visual Basic 6.0,:
- In Visual Basic 2005 and in Visual Basic .NET, the Short data type is equivalent to the Visual Basic 6.0 Integer data type.
- In Visual Basic 2005 and in Visual Basic .NET, the Integer data type is equivalent to the Visual Basic 6.0 Long data type.
- In Visual Basic 2005 and in Visual Basic .NET, the Long data type is 64-bit.
- In Visual Basic 2005 and in Visual Basic .NET, the complier directly supports the Decimal data type. In Visual Basic 6.0, because Decimal is a subtype of Variant, you cannot declare a type to be Decimal.
- Because Visual Basic 2005 and Visual Basic .NET do not support the Visual Basic
6.0 Currency data type, use the Decimal data type instead for this functionality.
- Because Visual Basic 2005 and Visual Basic .NET do not support the Visual Basic
6.0 fixed-length string, use a compatibility class for this
functionality.
- In Visual Basic 2005 and in Visual Basic .NET, the Date data type is not stored in a Double data type. Instead, the Date data type uses an 8-bit integer type internally. You can use
functions such as the ToOADate and the FromOADate functions to convert back and forth.
- Both the Char and the String data types use two bytes for each character.
- Because Visual Basic 2005 and Visual Basic .NET do not support the Visual Basic
6.0 Variant data type, use the System.Object type instead for this functionality. For example, you can use the
Object type when you declare a variable that may hold two different
types.
Literals
For the most part, literals are the same in Visual Basic 2005 and in Visual Basic .NET as
they are in Visual Basic 6.0.
- For Integer data types, use the following prefixes and suffixes:
- &H prefix for hexadecimal notation.
- &O prefix for octal notation.
- S suffix for the Short data type.
- I suffix for the Integer data type.
- L suffix for the Long data type.
For example: - For floating point data types, use the following suffixes:
- F suffix for the Single data type.
- R suffix for the Double data type.
- D suffix for the Decimal data type.
- For the Char data type, use the c suffix. For example:
Declaration
In Visual Basic 2005 and in Visual Basic .NET, you can declare a new variable and
assign an initial value at the same time. For example:
Dim MyInt As Integer = 25
Dim OtherInt As Integer = MyInt * 100
Multiple variables on the same line are of the same type. For example,
in the following statement,
MyVar1 is a
Variant data type in Visual Basic 6.0 but a
String data type in Visual Basic 2005 and in Visual Basic .NET:
Dim MyVar1, MyVar2 As String
You can still include different types in a declaration on the same line
so that the following declaration is still valid in Visual Basic 2005 and in Visual Basic .NET:
Dim x as Integer, y as String
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
311331
The behavior of variable declaration changes in Visual Basic 2005 and in Visual Basic .NET
Scope
In Visual Basic 6.0, you can declare a variable anywhere inside a
procedure. The variable has full procedure scope regardless of where the
declaration is located. This allows you access to the variable anywhere within
the same procedure. If the variable is declared inside a block such as a
For loop, a
Do loop, or an
If block, you can still access the variable outside the
block.
This behavior changes in Visual Basic 2005 and in Visual Basic .NET. If you declare a
variable in a block, that variable is only available inside that block.
Therefore, the variable only has block scope in Visual Basic 2005 and in Visual Basic .NET. A block is
defined as a set of statements that end with an
End, a
Loop, or a
Next statement.
Block scope works differently than procedure
scope. In block scope, if you declare a variable inside a block, the variable
does not lose its value when you exit the block. The value is still available
in case you need to re-enter the block. However, you cannot reference the
variable from outside the block.
For example, the following code
works in Visual Basic 6.0 but generates an error in Visual Basic 2005 and in Visual Basic .NET:
Dim i As Long
For i = 0 To 10
Dim multiples As Long
multiples = i * 3
Next i
MsgBox(multiples)
In Visual Basic 2005 and in Visual Basic .NET, the error indicates that the variable "multiples"
has not been declared. This error occurs on the following line of code because
you try to access the variable outside of the
For Next block:
MsgBox(multiples)
Enumerators
Enumerations are types that give symbolic representation to a set
of values. Enumerations make the program much easier to write, to read, and to
maintain because the code uses the symbolic name rather than the value. In
addition, debugging tools display the symbolic name.
Because every
enumerator inherits from the
System.Enum class (which inherits from the
System.ValueType class, which in turn inherits from
System.Object), enumerators are more than just symbols. Enumerators are value
types that have their own set of methods.
You can assign a particular
value to enumeration members by using the equal sign (=). If the first member
is not initialized to a value, the member is assigned a value of zero. If the
remaining members are not initialized, they are assigned the value of the
previous member plus one.
Enumerators are strongly typed. They can be
a
Byte, a
Short, an
Integer, or a
Long data type. If you do not supply a data type, the enumerator uses
the
Integer data type by default.
Both of the following
declarations are valid in Visual Basic 2005 and in Visual Basic .NET:
Public Enum MyColor as Integer
Red = 0
Green = 1
Blue = 2
Orange = 3
End Enum
Public Enum MyColor
Red
Green
Blue
Orange
End Enum
Structures
The structure data type replaces the user-defined type (UDT) from
Visual Basic 6.0. The structure data type inherits from the
System.ValueType class. The following list outlines some of the differences
between the structure data type and the user-defined type:
- Unlike UDTs, the structure data type is not limited to 64
kilobytes.
- Unlike UDTs, structures can contain methods, implement
interfaces, and declare events.
In Visual Basic 2005 and in Visual Basic .NET, the structure data type is very similar to a
class data type except that a structure data type is a value type (whereas a
class data type is a reference type). For increased efficiency, you may want to
use structure data types if you do not need the overhead of maintaining a
reference pointer. However, because a structure data type is a value type, it
is not garbage collected.
Reference Types
Reference types store the data on the run-time heap and store a
pointer to the data on the stack. As a result, a reference type is subject to
garbage collection.
You can only access the data in reference types
through the reference pointer. To copy the reference rather than the actual
data, you can assign a variable to the reference type. Therefore, every time
your code references any member of an object on the heap, code must be
generated and run to dereference the pointer to perform the necessary actions.
This may impact performance.
Reference types include the following
data types:
- String
- Array
- Class
- Interface
- Delegate
String
Although
String data types may appear to be the same in Visual Basic 2005 and in Visual Basic .NET as they
are in Visual Basic 6.0, Visual Basic 2005 and Visual Basic .NET
String data types are invariant.
Because
String data types are read-only after initialization, you cannot
directly modify their content. The
String variable contains a pointer to memory that contains the actual
data. Any modification to the string deallocates the current memory block and
allocates a new memory block for the new value. For example:
Dim strS as String
strS="Hello" 'Allocates memory for "Hello".
strS=strS & " World" 'Deallocates memory for "Hello" and reallocates memory for "Hello World".
Visual Basic 6.0 allocates string memory in the same manner. However,
in Visual Basic 6.0 and earlier, you can also directly modify the contents of
the string memory by using the
Mid statement. For example:
Dim strS as String
strS="Hello World"
Mid(strS, 7,5)="There"
In Visual Basic 2005 and in Visual Basic .NET, the
Mid statement operates through concatenation. The
Mid statement does not directly modify the string memory. Instead,
the
Mid statement deallocates and reallocates memory just like all other
string operations.
The following lists outline the advantages and
disadvantages of an invariant
String data type.
Advantages of Invariance- Because the value of a string buffer can never change, you
can copy a string by just copying the pointer. Any code that attempts to modify
the string will allocate new memory and leave the old value as is. When no
variable points to the string memory, the garbage collector will clean up the
string memory.
- When you modify a buffer in a multithreaded environment,
you must lock the contents to avoid contention with another thread. This
locking process incurs a performance overhead. However, because string
variables are invariant in Visual Basic 2005 and in Visual Basic .NET, the memory buffer that you point
to is read-only and does not require locking. Therefore, you do not impact
performance.
Disadvantages of Invariance- It is costly to deallocate and reallocate string memory,
especially when you have many concatenations.
Note If the cost of deallocating and reallocating string greatly
affects performance, you can use the
StringBuilder class in Visual Basic 2005 and in Visual Basic .NET. The
StringBuilder class uses the benefits of the
Mid statement from Visual Basic 6.0. You will notice performance
benefits at approximately 300 string concatenations.
Array
All array types implicitly inherit from the
System.Array class, which inherits from
System.Object. Arrays are allocated on the managed heap. In Visual Basic 6.0,
you can use "Option Base" for 0 or 1 based arrays. In Visual Basic 2005 and in Visual Basic .NET, arrays
are 0 based. An array that you declare as size 10 actually has 11 elements from
0 to 10.
- If all of the dimensions of the array are zero, the array
has a length of zero, and the array is empty.
- If the array consists of reference types, each array
element is initialized to null.
- If the array consists of value types, the members are
initialized to the default value for their type (that is, Integer members are initialized to zero).
- Visual Basic .NET allows arrays of arrays. For example:
Dim Sales()() As Double = New Double(11)() {} ' Allocate top-level array.
Dim Month As Integer ' Counter variable for month.
Dim Days As Integer ' Days in given month for this year.
For Month = 0 To 11
Days = DateTime.DaysInMonth(Year(Now), Month + 1) ' Get number of days.
Sales(Month) = New Double(Days - 1) {} ' Assign array for this month.
Next Month
Sales(2)(3) = 1234.56 'Assign value for March 4.
Debug.WriteLine(Sales(2)(3).ToString)
- You can initialize arrays during declaration.
- By inheriting from System.Array, each array reference type automatically inherits a set of System.Array methods and properties such as Rank, Length, GetLength, and GetUpperBound.
- In Visual Basic 6.0, you can use the ReDim statement to redimension a variable so that the variable has a
different number of indexes. However, you cannot do this in Visual Basic 2005 or in Visual Basic .NET.
The following Visual Basic 6.0 statements no longer work in Visual Basic 2005 or in Visual Basic .NET:
Dim MyArray( ) as Integer
Redim MyArray(5,3)
If you attempt to use any of these statements, you receive the
following error message: 'Redim' cannot change the
number of dimensions of an array.
To resolve this problem, change
the preceding code as follows:
Dim MyArray(,) as Integer
Redim MyArray(5,3)
- Visual Basic 2005 and Visual Basic .NET still support the Erase statement. The Erase statement creates an empty array without rank or
dimensions.
Class
A class is a data structure that may contain data members (such
as constants and variables), function members (such as methods, properties,
indexers, operators, events, and constructors), and nested types. Class types
support inheritance. Inheritance is a mechanism whereby a derived class can
extend and specialize a base class.
As a significant improvement from
Visual Basic 6.0, Visual Basic 2005 and Visual Basic .NET are true object-oriented programming
languages. Visual Basic 2005 and Visual Basic .NET support implementation inheritance by allowing you
to define classes that serve as the basis for derived classes. Derived classes
inherit and can extend the properties and the methods of the base class.
Derived classes can also override inherited methods with new
implementations.
Interface
An interface is a contract. A class or a structure that
implements the interface must adhere to the contract. The contract specifies
the members that must be supplied by the class that implements the interface.
The interface is a list of functions. The interface contains
Sub or
Function methods, properties, and events. However, the interface provides
no implementation itself.
Visual Basic 6.0 can consume interfaces but
cannot create them directly. To work around this behavior, you can create an
empty class and implement it as you would an interface. However, this technique
can be awkward and can risk accidental implementation of the interface
class.
As a significant improvement from Visual Basic 6.0, Visual Basic 2005 and Visual Basic .NET provide the formal declaration of the interface and use the much
improved version of the Implements keyword to implement interfaces. Visual Basic 2005 and Visual Basic .NET support interface inheritance by allowing you to define interfaces
that serve as contracts or as protocols, which must be implemented by classes
that inherit from interfaces.
Delegate
Visual Basic 2005 and Visual Basic .NET introduce the delegate reference type. The
Delegate reference type is central to the programming model of the common
language runtime.
Delegates are classes that hold references to
procedures. They are similar to a function pointer in C or C++. However, in C
or C++, the address of a function is just a memory address. No additional
information is associated with this address, such as the number or the type of
arguments. Therefore, a C or a C++ function pointer is not type safe. Because
the .NET Framework provides a type-safe environment, it provides a managed,
type-safe function pointer, which is the delegate type.
A delegate is
derived from the
System.Delegate class. Although a function pointer can only reference shared
functions, a delegate can reference both shared and instance methods. For an
instance method, the delegate stores a reference not only to the method's entry
point, but also to the object instance.
The event
model in Visual Basic 2005 and in Visual Basic .NET uses delegates to bind events to the methods that are used to handle
them. The delegate allows other classes to register for event notification by
specifying a handler method. When the event occurs, the delegate calls its
bound method.
Casting
There are two types of casting:
- Implicit casting. Implicit casting is transparent to users. The compiler
automatically converts from one data type to another. The predefined, implicit
conversions always succeed and never cause an error.
- Explicit casting. Explicit casts are called in the code. Explicit casts cannot
guarantee success and may lose information if you cast from a larger type to a
smaller type.
Boxing and Unboxing
In some cases, you may want to treat an instance of a value type
like an instance of a reference type. Boxing provides this mechanism.
Boxing converts a value type to a reference type by performing the following
steps:
- Allocates memory on the managed heap to store the
value.
- Copies the value to the managed heap.
- Stores the reference to the data (address of the object) on
the stack.
Unboxing converts an instance of a reference type back to its
original value type by returning a pointer to the data within a boxed subject.
The pointer does not include the usual overhead that is associated with a true
object.