Section 1.2. What Is Visual Basic .NET?


1.2. What Is Visual Basic .NET?

Visual Basic .NET is a programming language designed to create applications that work with Microsoft's .NET Framework. The .NET platform, in turn, addresses many of the limitations of "classic" COM, Microsoft's Component Object Model, which provided one approach toward application and component interoperability. These limitations included type incompatibilities when calling COM components, versioning difficulties when developing and installing new versions of COM components (known as "DLL hell"), and the need for developers to write a certain amount of code (mostly in C++) to handle the COM "plumbing." In contrast to pre-.NET VB, with its reliance on COM, Visual Basic as a .NET language offers a number of new features and advantages. Let's take a look at some of these.

1.2.1. Object Orientation

With the release of Version 4, Visual Basic added support for classes and class modules and, in the process, became an object-oriented programming (OOP) language. Yet the debate persists about whether pre-.NET Visual Basic was a "true" object-oriented language, or whether it only supported limited features of object orientation. Detractors point out that Visual Basic did not support inheritance of a base class's functionality, only of its interface or signature. While Visual Basic still had a solid base of object-oriented features, purists emphasized the very real limitations in VB's OOP implementation.

While the object-oriented character of previous versions of VB may be in doubt, there is no question that .NET is an object-oriented programming platform. In fact, even if Visual Basic .NET is used to write what appears to be procedural code, it is object-oriented "under the hood." As an example, consider the clearly procedural, non-object-oriented program shown in Example 1-3.

Example 1-3. A procedural program in .NET

 Module Module1    Public Sub Main()       Dim x As Integer       x = 10       MsgBox(Increment(x))    End Sub    Private Function Increment(ByVal baseValue As Integer) As Integer       Return baseValue + 1    End Function End Module 

If you use ILDASM (.NET's equivalent of a disassembler) to look at the IL ("Intermediate Language," somewhat similar to assembly language in the non-.NET world) generated for this source code (see Figure 1-1), you see that internally, Module1 is in fact defined as a class that has two methods, Increment and Main.

Figure 1-1. A program viewed through ILDASM


1.2.2. A Common Type System

Traditionally, one of the problems of calling routines written in other languages from Visual Basic, or of calling Visual Basic routines from other languages, is that such inter-language calls presuppose a common type system . This is the case when calling Win32 API functions from Visual Basic, but it also applies to attempts to call methods in a VB COM component from other languages, or to call methods in a non-VB COM component from VB.

For instance, until the addition of the AddressOf operator, which obtained the memory address of a procedure, there was no way to indicate a "callback" function, a requirement of many Win32 API enumeration functions. As another example, it is expected that members of structures passed to Win32 API functions be aligned or padded in specific ways, something that VB programmers had great difficulty accomplishing.

Problems of type compatibility tended to occur most often when scripted applications were used to call and pass arguments to COM components. An excellent example is the attempt to pass an array from a script written in JScript to a COM component. COM sees JScript arrays as a string of comma-delimited values rather than as a COM-compatible array (called a SafeArray). This, and similar problems, caused no end of type-related headaches.

The .NET platform removes these difficulties by providing a Common Type System (CTS). Ultimately, all data types are either classes or structures defined by or inherited from the .NET Base Class Library. Having this Common Type System means that .NET components are truly language-independent, and that a .NET component written in one language will be seamlessly interoperable with .NET components written in any other .NET language. The problem of incompatible types simply disappears.

On the surface, VB appears to have retained its old type system. VB still supports the Long data type, for instance, although it is now a 64-bit data type instead of the 32-bit data type of VB 4 through VB 6. Most of the following .NET code is strikingly similar to VB 6 in its use of data types.

     Public Module GeneralCode        Public Sub Main()           Dim infoText As String = "This is a string."           Dim bigNumber As Long = 12344           Dim tinyNumber As Integer = 10        End Sub     End Module 

However, if you use ILDASM to examine the IL generated from this Visual Basic code, you see that VB data types are merely wrappers for data types provided by the .NET Framework. Where you expect to see Integer and Long, you instead see int32 and int64, two of the core .NET data types.

     .method public static void  Main() cil managed     {       .entrypoint       .custom instance void           [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )       // Code size       17 (0x11)       .maxstack  1       .locals init ([0] int64 bigNumber,               [1] string infoText,               [2] int32 tinyNumber)       IL_0000:  ldstr      "This is a string."       IL_0005:  stloc.1       IL_0006:  ldc.i4     0x3038       IL_000b:  conv.i8       IL_000c:  stloc.0       IL_000d:  ldc.i4.s   10       IL_000f:  stloc.2       IL_0010:  ret    } // end of method GeneralCode::Main 

1.2.3. Access to System Services: The Framework Class Library

Ever since VB added support for calls to the Windows and Win32 APIs, many Visual Basic programmers have come to regard API programming as a kind of black art. Not only was there a confusing and seemingly limitless array of functions that might be called, but the craft of passing parameters to routines and receiving their return values was equally mysterious. Moreover, with the growing emphasis on object-oriented programming, the Win32 API, with its procedural approach to programming, seemed more and more archaic.

The Declare statement still appears in the .NET Visual Basic language, and programmers can continue to use the Win32 API and routines from other external Windows DLLs. However, many of the common system services provided by the Win32 API and other COM components are now available through the .NET Framework Class Library. The Framework Class Library is a collection of classes, class members, and other OOP-enabled elements, arranged in a convenient hierarchy of logical "namespaces" (read more about these in Chapter 2).

To get some sense of the difference in programming style between the Win32 API and the .NET Framework Class Library, as well as to appreciate the simplicity and ease with which the Framework Class Library can be accessed, compare Examples Example 1-4 and Example 1-5. Example Example 1-4 is a VB 6 routine that adds an entry in the registry that will load a particular program on Windows startup. As is clear in the code, all API constants must be defined, as must the API functions themselves. The API functions must be called correctly, using the ByVal keyword, to avoid passing a BSTR rather than a C null-terminated string to the RegSetValueEx function. Neglect this important rule if you like to see applications crash frequently for no apparent reason.

Example 1-4. Writing to the registry using the Win32 API

 Private Const ERROR_SUCCESS = 0& Private Const HKEY_CLASSES_ROOT = &H80000000 Private Const HKEY_CURRENT_CONFIG = &H80000005 Private Const HKEY_CURRENT_USER = &H80000001 Private Const HKEY_DYN_DATA = &H80000006 Private Const HKEY_LOCAL_MACHINE = &H80000002 Private Const HKEY_PERFORMANCE_DATA = &H80000004 Private Const HKEY_USERS = &H80000003 Private Const REG_SZ = 1 Private Const KEY_SET_VALUE = &H2 Private Declare Function RegCloseKey Lib "advapi32.dll" _       (ByVal hKey As Long) As Long Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _       Alias "RegOpenKeyExA" _       (ByVal hKey As Long, ByVal lpSubKey As String, _       ByVal ulOptions As Long, ByVal samDesired As Long, _       phkResult As Long) As Long Private Declare Function RegSetValueEx Lib "advapi32.dll" _       Alias "RegSetValueExA" _       (ByVal hKey As Long, ByVal lpValueName As String, _       ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, _       ByVal cbData As Long) As Long Private Sub LoadByRegistry()    Dim hKey As Long    Dim nResult As Long    Const cPGM As String = "C:\Test\TestStartup.exe"    nResult = RegOpenKeyEx(HKEY_CURRENT_USER, _       "Software\Microsoft\Windows\CurrentVersion\Run", 0, _       KEY_SET_VALUE, hKey)    If (nResult = ERROR_SUCCESS) Then       RegSetValueEx hKey, "MyVBApp", 0, REG_SZ, ByVal cPGM, Len(cPGM)       RegCloseKey hKey    End If End Sub 

In contrast, Example 1-5 shows the comparable .NET code that uses the RegistryKey class in the Framework Class Library's Microsoft.Win32 namespace. The code is short and simple and, therefore, far less error-prone.

Example 1-5. Writing to the registry using the Framework Class Library

 ' ----- "Imports Microsoft.Win32" included at top of file. Private Const TargetFile As String = "C:\Test\TestStartup.exe" Private Shared Sub LoadByRegistry()    Dim hive As RegistryKey = Registry.CurrentUser    Dim targetKey as RegistryKey = hive.OpenSubKey( _       "Software\Microsoft\Windows\CurrentVersion\Run", True)    targetKey.SetValue("MyVBApp", TargetFile)    targetKey.Close() End Sub 

No worries about putting ByVal in the right place. No messy declarations muddying up the code. Just nice, clean, obvious logic. This code could be simplified even more by using the registry management features available in the new Visual Basic My Namespace feature. See the Registry Object entry in Chapter 13 for additional information.

The .NET Framework Class Libraries (FCL) is a gigantic set of classes, built upon the smaller Base Class Libraries (BCL). FCL adds a lot of the convenience features, such as the Windows Forms namespaces (for Windows desktop development). When you are using the .NET libraries, there is no clear division between BCL and FCL; there are no BCL or FCL prefixes on class names. Somewhere at Microsoft there is probably a document that clearly lists the differences, but for most programmers, it really doesn't matter. Whatever you call it, it's still a big heap of functionality. Many resources use the terms interchangeably, and this book continues that practice.

1.2.4. A Common Runtime Environment

Although VB had traditionally shielded the developer from many of the intricacies of Windows as an operating system, or of COM as a method for interoperability, some knowledge of how the system worked was still essential to maintain problem-free applications. Programs and components written with one tool did not always work well with code from other tools. Working with the Win32 API often required a more advanced introduction to Windows development concepts than the typical novice Visual Basic programmer was ready to handle. Not all COM components were created equal either. It was quite easy to generate a COM component in C++ that could not be used in VB, and vice versa. Such incompatibilities kept many a programmer from developing and deploying components in their language of choice.

Under .NET, many problems like these are eliminated because of the .NET platform's Common Language Runtime (CLR). The CLR, as its name clearly implies, provides a variety of common services to applications and processes running under the .NET platform, regardless of the language in which they were originally written. These services include memory management and garbage collection. They also include a unified system of exception handling and the ability to use the same set of debugging tools on all code, regardless of the original .NET language used. A common set of data types ensures that data and classes interact easily between the various .NET languages. Many of these features are described later in Part I of this book.

1.2.5. Naming Conventions

Although naming conventions are not strictly part of a programming language, most Visual Basic developers had adopted some form of the prefix-based "Hungarian" naming system developed many years ago by Charles Simonyi. With the release of .NET, Microsoft now recommends a new naming system. This system dispenses with the endless lists of type-specific prefixes and instead assigns names to elements (classes, functions, local variables, global constants, etc.) based solely on what they are. So a variable that holds a customer name is no longer sCustName (with "s" for "string) or even lpszCustName (don't ask); you now simply use customerName.

The new conventions include two types of naming: "Pascal Casing" and "Camel Casing." All names are mixed case, with a capital letter appearing at the start of each new word within the name. Pascal Casing also capitalizes the first letter, and it is used for all public class members and global elements. Camel Casing includes a lowercase initial letter, and it is used for private members, procedure arguments, and local variables. There are some additional details to the rules, and some people differ on when to use Pascal Casing and when to use Camel Casing. The online help included with Visual Studio includes an entry that discusses these conventions in more detail.

In keeping with the spirit of .NET programming, all .NET examples in this book employ the new naming conventions.




Visual Basic 2005(c) In a Nutshell
Visual Basic 2005 in a Nutshell (In a Nutshell (OReilly))
ISBN: 059610152X
EAN: 2147483647
Year: 2004
Pages: 712

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net