New data types in Visual Studio 2005 and in Visual Studio .NET (311327)



The information in this article applies to:

  • Microsoft Visual Studio 2005 Standard Edition
  • Microsoft Visual Studio 2005 Professional Edition
  • Microsoft Visual Studio .NET (2003), Professional Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Professional Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition
  • Microsoft .NET Framework Class Libraries 1.0

This article was previously published under Q311327

SUMMARY

This article describes the new data types that are available in Microsoft Visual Studio 2005 and in Microsoft Visual Studio .NET and the differences between the new Visual Studio 2005 and Visual Studio .NET data types and the Microsoft Visual Basic 6.0 data types. In addition, this article explains how you can use the Object type to achieve the functionality of the Variant type.

In Visual Studio 2005 and in Visual Studio .NET, the common language runtime provides the base classes that include basic data types, collection classes, and other general classes. The common type system sets the key foundation for multiple language support.

Previously, each programming language represented data types in its own way. Now, the common type system provides every language in Visual Studio 2005 and in Visual Studio .NET with a basic set of data types. Every data type is derived from the System.Object class. In addition, every data type supports a minimum set of methods. Because all languages use the same library of types, you can call one language from another without having to convert the type or the call conventions.

In addition, the .NET run-time environment is designed to be safe and secure. The .NET run-time environment enforces strict rules to guarantee the safety of types. The Common Language Specification defines a set of programmatically verifiable rules. These rules govern the interoperation of types that are authored in different programming languages. These rules also establish requirements for Common Language Specification compliance. Visual Studio 2005 and Visual Studio .NET languages such as Microsoft Visual Basic 2005, Microsoft Visual Basic .NET, Microsoft Visual C# 2005, and Microsoft Visual C# .NET comply with the Common Language Specification.

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:
NameObjectDescriptionDefault Value
ByteSystem.Byte1 byte unsigned integer0
ShortSystem.Int162 byte signed integer0
IntegerSystem.Int324 byte signed integer0
LongSystem.Int648 byte signed integer0
SingleSystem.Single4 byte floating point0
DoubleSystem.Double8 byte floating point0
DecimalSystem.Decimal16 byte decimal0D
BooleanSystem.BooleanTrue or FalseFalse
DateSystem.DateTimeDate time stamp#01/01/0001 12:00:00 AM#
CharSystem.CharSingle unicode characterChrW(0)
StringSystem.StringMultiple unicode charactersnull 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:

    14, 3S, 70I, 53L, &H000B

  • 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:

    "A"c

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:
  1. Allocates memory on the managed heap to store the value.
  2. Copies the value to the managed heap.
  3. 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.

Modification Type:MajorLast Reviewed:2/3/2006
Keywords:kbvs2005swept kbvs2005applies kbinfo KB311327 kbAudDeveloper