Tuesday, March 3, 2020
Modules, Structures, and Classes
Modules, Structures, and Classes There are just three ways to organize a VB.NET application. ModulesStructuresClasses But most technical articles assume that you already know all about them. If youre one of the many who still have a few questions, you could just read past the confusing bits and try to figure it out anyway. And if you have a lot of time, you can start searching through Microsofts documentation: A Module is a portable executable file, such as type.dll or application.exe, consisting of one or more classes and interfaces.A Class statement defines a new data type.The Structure statement defines a composite value type that you can customize. Right, then. Any questions? To be a bit more fair to Microsoft, they have pages and pages (and more pages) of information about all of these that you can wade through. And they have to be as exact as possible because they set the standard. In other words, Microsofts documentation sometimes reads like a law book because it is a law book. But if youre just learning .NET, it can be very confusing! You have to start somewhere. Understanding the three fundamental ways that you can write code in VB.NET is a good place to start. You can write VB.NET code using any of these three forms. In other words, you can create a Console Application in VB.NET Express and write: Module Module1Ã Ã Ã Sub Main()Ã Ã Ã Ã Ã Ã MsgBox(This is a Module!)Ã Ã Ã End SubEnd ModuleClass Class1Ã Ã Ã Sub Main()Ã Ã Ã Ã Ã Ã MsgBox(This is a Class)Ã Ã Ã End SubEnd ClassStructure Struct1Ã Ã Ã Dim myString As StringÃ Ã Ã Sub Main()Ã Ã Ã Ã Ã Ã MsgBox(This is a Structure)Ã Ã Ã End SubEnd Structure This doesnt make any sense as a program, of course. The point is that you dont get a syntax error so its legal VB.NET code. These three forms are the only way to code the queen bee root of all of .NET: the object. The only element that interrupts the symmetry of the three forms is the statement: Dim myString As String. That has to do with a Structure being a composite data type as Microsoft states in their definition. Another thing to notice is that all three blocks have a Sub Main() in them. One of the most fundamental principals of OOP is usually called encapsulation. This is the black box effect. In other words, you should be able to treat each object independently and that includes using identically named subroutines if you want to. Classes Classes are the right place to start because, as Microsoft notes, A class is a fundamental building block of object-oriented programming (OOP). In fact, some authors treat modules and structures as just special kinds of classes. A class is more object oriented than a module because its possible to instantiate (make a copy of) a class but not a module. In other words, you can code ... Public Class Form1Ã Ã Ã Private Sub Form1_Load( _Ã Ã Ã Ã Ã Ã ByVal sender As System.Object, _Ã Ã Ã Ã Ã Ã ByVal e As System.EventArgs) _Ã Ã Ã Ã Ã Ã Handles MyBase.LoadÃ Ã Ã Ã Ã Ã Dim myNewClass As Class1 New Class1Ã Ã Ã Ã Ã Ã myNewClass.ClassSub()Ã Ã Ã End SubEnd Class (The class instantiation is emphasized.) It doesnt matter whether the actual class itself, in this case, ... Public Class Class1Ã Ã Ã Sub ClassSub()Ã Ã Ã Ã Ã Ã MsgBox(This is a class)Ã Ã Ã End SubEnd Class ... is in a file by itself or is part of the same file with the Form1 code. The program runs exactly the same way. (Notice that Form1 is a class too.) You can also write class code that behaves much like a module, that is, without instantiating it. This is called a Shared class. The article Static (that is, Shared) versus Dynamic Types in VB.NET explains this in much more detail. Another fact about classes should also be kept in mind. Members (properties and methods) of the class only exist while the instance of the class exists. The name for this is scoping. That is, the scope of an instance of a class is limited. The code above can be changed to illustrate this point this way: Public Class Form1Ã Ã Ã Private Sub Form1_Load( _Ã Ã Ã Ã Ã Ã ByVal sender As System.Object, _Ã Ã Ã Ã Ã Ã ByVal e As System.EventArgs) _Ã Ã Ã Ã Ã Ã Handles MyBase.LoadÃ Ã Ã Ã Ã Ã Dim myNewClass As Class1 New Class1Ã Ã Ã Ã Ã Ã myNewClass.ClassSub()Ã Ã Ã Ã Ã Ã myNewClass NothingÃ Ã Ã Ã Ã Ã myNewClass.ClassSub()Ã Ã Ã End SubEnd Class When the second myNewClass.ClassSub() statement is executed, a NullReferenceException error is thrown because the ClassSub member doesnt exist. Modules In VBÃ 6, it was common to see programs where most of the code was in a module (A .BAS, file rather than, for instance, in a Form file such as Form1.frm.) In VB.NET, both modules and classes are in .VB files. The main reason modules are included in VB.NET is to give programmers a way to organize their systems by putting code in different places to fine tune the scope and access for their code. (That is, how long members of the module exist and what other code can reference and use the members.) Sometimes, you may want to put code into separate modules just to make it easier to work with. All VB.NET modules are Shared because they cant be instantiated (see above) and they can be marked Friend or Public so they can be accessed either within the same assembly or whenever theyre referenced. Structures Structures are the least understood of the three forms of objects. If we were talking about animals instead of objects,Ã the structure would be an Aardvark. The big difference between a structure and a class is that a structure is a value type and a class is a reference type. What does that mean? Im so glad you asked. A value type is an object that is stored directly in memory. An Integer is a good example of a value type. If you declared an Integer in your program like this ... Dim myInt as Integer 10 ... and you checked the memory location stored in myInt, you would find the value 10. You also see this described as being allocated on the stack. The stack and the heap are simply different ways of managing the use of computer memory. A reference type is an object where the location of the object is stored in memory. So finding a value for a reference type is always a two step lookup. A String is a good example of a reference type. If you declared a String like this ... Dim myString as String This is myString ... and you checked the memory location stored in myString, you would find another memory location (called a pointer - this way of doing things is the very heart of C style languages). You would have to go to that location to find the value This is myString. This is often called being allocated on the heap. The stack and the heap Some authors say that value types arent even objects and only reference types can be objects. Its certainly true that the sophisticated object characteristics like inheritance and encapsulation are only possible with reference types. But we started this whole article by saying that there were three forms for objects so I have to accept that structures are some sort of object, even if theyre non-standard objects. The programming origins of structures go back to file-oriented languages like Cobol. In those languages, data was normally processed as sequential flat files. The fields in a record from the file were described by a data definition section (sometimes called a record layout or a copybook). So, if a record from the file contained: 1234567890ABCDEF9876 The only way you would know that 1234567890 was a phone number, ABCDEF was an ID and 9876 was $98.76 was through the data definition. Structures help you accomplish this in VB.NET. Structure Structure1Ã Ã Ã VBFixedString(10) Dim myPhone As StringÃ Ã Ã VBFixedString(6) Dim myID As StringÃ Ã Ã VBFixedString(4) Dim myAmount As StringEnd Structure Because a String is a reference type, its necessary to keep the length the same with the VBFixedString attribute for fixed length records. You can find an extended explanation of this attribute and attributes in general in the article Attributes in VB .NET. Although structures are non-standard objects, they do have a lot of capability in VB.NET. You can code methods, properties, and even events, and event handlers in structures, but you can also use more simplified code and because theyre value types, processing can be faster. For example, you could recode the structure above like this: Structure Structure1Ã Ã Ã VBFixedString(10) Dim myPhone As StringÃ Ã Ã VBFixedString(6) Dim myID As StringÃ Ã Ã VBFixedString(4) Dim myAmount As StringÃ Ã Ã Sub mySub()Ã Ã Ã Ã Ã Ã MsgBox(This is the value of myPhone: myPhone)Ã Ã Ã End SubEnd Structure And use it like this: Dim myStruct As Structure1myStruct.myPhone 7894560123myStruct.mySub() Its worth your time to play around with structures a bit and learn what they can do. Theyre one of the odd corners of VB.NET that can be a magic bullet when you need it.