Our "Hello, world" program illustrated the basic structure of a VB.NET program, but we will need a slightly more elaborate example to show the use of other basic programming constructs, such as variables , expressions, and control structures. The example illustrates a number of features, which we will explain later. Our next example is a simple calculator for an IRA account. We calculate the accumulation of deposits to an IRA of $2000.00 a year at 6% interest for 10 years , assuming that each deposit is made at the end of the year. Our calculation is performed in two ways: The example program is in the folder Ira\Step1 . ' Ira.vb - Step 1 Imports System Module Ira Public Sub Main() Dim years As Integer = 10 Dim rate As Decimal = 0.06D Dim amount As Decimal = 2000D Dim interest As Decimal Dim total As Decimal = 0D Console.WriteLine(_ "{0,4} {1,12} {2,12} {3,12}", _ "Year", "Amount", "Interest", "Total") Dim i As Integer = 1 While i <= years interest = total * rate total += amount + interest Console.WriteLine(_ "{0, -4} {1, 12:C} {2, 12:C} {3, 12:C}", _ i, amount, interest, total) i += 1 End While Console.WriteLine() Console.WriteLine(_ "Total using formula = {0}", _ IraTotal(years, rate, amount)) End Sub Private Function IraTotal(ByVal years As Integer, _ ByVal rate As Double, ByVal amount As Double) As Double Dim total As Double = _ amount * (Math.Pow(1 + rate, years) - 1) / rate Dim total_in_cents As Long = Math.Round(total * 100) total = total_in_cents / 100 Return total End Function End Module If you compile and run it, you will see this output: Year Amount Interest Total 1 ,000.00 Year Amount Interest Total 1 $2,000.00 $0.00 $2,000.00 2 $2,000.00 $120.00 $4,120.00 3 $2,000.00 $247.20 $6,367.20 4 $2,000.00 $382.03 $8,749.23 5 $2,000.00 $524.95 $11,274.19 6 $2,000.00 $676.45 $13,950.64 7 $2,000.00 $837.04 $16,787.68 8 $2,000.00 $1,007.26 $19,794.94 9 $2,000.00 $1,187.70 $22,982.63 10 $2,000.00 $1,378.96 $26,361.59 Total using formula = 26361.59 .00 ,000.00 2 ,000.00 0.00 ,120.00 3 ,000.00 7.20 ,367.20 4 ,000.00 2.03 ,749.23 5 ,000.00 4.95 ,274.19 6 ,000.00 6.45 ,950.64 7 ,000.00 7.04 ,787.68 8 ,000.00 ,007.26 ,794.94 9 ,000.00 ,187.70 ,982.63 10 ,000.00 ,378.96 ,361.59 Total using formula = 26361.59 Variables In VB.NET variables are always of a specific data type. Some common types are Integer for integers and Double for floating-point numbers . VB.NET has the Decimal data type, which has a high degree of precision, suitable for financial calculations. You must declare variables before you use them, and you may optionally initialize them. Dim years As Integer = 10 Dim rate As Decimal = 0.06D Dim amount As Decimal = 2000D Dim interest As Decimal Dim total As Decimal = 0D If an initial value is not specified in the declaration, the variable is automatically initialized . For example, an uninitialized Decimal variable is set to zero. We will discuss initialization later in the chapter. Variables must be either local within a method or members of a class. There are no global variables in VB.NET. Literals A literal is used when you explicitly write a value in a program rather than represent it with a variable name . An integer literal is represented by an ordinary base-10 integer, an octal integer, or a hexadecimal integer. An octal integer is indicated with the &O [1] prefix, such as &O77 (which is 63 in base 10). A hexadecimal literal is indicated with the &H prefix, such as &H7FFF (which is 32,767 in base 10). The suffixes S , I , and L are used to designate Short, Integer, and Long. A floating-point literal is represented by a number with a decimal point or by exponential notation. You may determine the type [2] that is used for storing a literal by a suffix. The suffix F indicates single precision (32-bit) floating point. The suffix R indicates double precision (64-bit) floating point. The Single and Double types are often suitable for scientific and engineering purposes. The suffix D indicates Decimal , which is usually more suitable for financial calculations, and it represents a high precision (128-bit) fixed-point number. [1] That is the letter O, not the number 0. [2] We discuss VB.NET types, such as Single , Double , and Decimal , later in the chapter. Dim rate As Decimal = 0.06D Dim amount As Decimal = 2000D A character string literal is represented by a sequence of characters in double quotes. Dim file1 As String = "c:\test2.txt" Dim str As String = "Welcome to VB.NET" VB.NET Operators and Expressions You can combine variables and literals via operators to form expressions. The VB.NET operators are similar to those in other .NET languages. One of the newest features of VB.NET is its new compound assignment operators that perform arithmetic operations as part of the assignment. Here are examples from the Ira program: i += 1 ' this is equivalent to i = i + 1 total += amount + interest ' this is equivalent to ' total = total + amount + interest There are six new compound assignment operators available in VB.NET. They are demonstrated in the following example: Dim x As Single = 4.6 x *= 2 ' multiply x by 2 x /= 2 ' divide x by 2 x += 2 ' add 2 to x x -= 2 ' subtract 2 from x x \= 2 ' divide (integer) x by 2 There is also a compound assignment operator for string concatenation. The following expression concatenates an exclamation point to the end of the string contained in the variable buf: Dim buf As String = "Hello" x &= "!" New Operators in VB.NET VB.NET introduces several operators that are new to VB6 programmers. OrElse and AndAlso provide shortcut evaluation of conditional expressions. And the assignment operators ^= , *= , /= , \= , += , -= , and &= provide shortcuts for common operations. | Precedence rules determine the order in which operators within expressions are evaluated. Operators are applied in the precedence order shown in Table 3-1. Operators within a row have equal precedence. For operators of equal precedence within the same expression, the order of evaluation is from left to right, as they appear in an expression. Order of evaluation can be explicitly controlled by using parentheses. Table 3-1. Operator Precedence in VB.NET Category | Operators | Primary | All non-operator expressions (literals, variables) | Exponentiation | ^ | Unary negation | +, - | Multiplicative | *, / | Integer division | \ | Modulus | Mod | Additive | +, - | Concatenation | & | Relational | =, <>, <, >, <=, >=, Like, Is, TypeOf...Is | Conditional NOT | Not | Conditional AND | And, AndAlso | Conditional OR | Or, OrElse | Conditional XOR | Xor | Output and Formatting The Console class in the System namespace supports two simple methods for performing output: You can write out other data types by relying on the ToString method of System.Object , which will provide a string representation of any data type. System.Object is the base class from which all classes inherit. We will discuss this class in Chapter 6, where you will also see how to override ToString for your own custom data types. You can use the string concatenation operator & to build up an output string. Dim x As Integer = 24 Dim y As Integer = 5 Dim z As Integer = x * y Console.Write("Product of " & x.ToString() + _ " and " & y.ToString()) Console.WriteLine(" is " & z.ToString()) The output is all on one line: Product of 24 and 5 is 120 Placeholders A more convenient way to build up an output string is to use placeholders such as {0}, {1}, and so on. An equivalent way to do the output shown above is Console.WriteLine("Product of {0} and {1} is {2}", x, y, z) The program OutputDemo illustrates the output operations just discussed. We will generally use placeholders for our output from now on. Placeholders can be combined with formatting characters to control output format. Format Strings VB.NET has extensive formatting capabilities, which you can control through placeholders and format strings. -
Simple placeholders: {n}, where n is 0, 1, 2, , indicating which variable to insert -
Control width: {n,w}, where w is width (positive for right justified and negative for left justified) of the inserted variable -
Format string: {n:S}, where S is a format string indicating how to display the variable -
Width and format string: {n,w:S} A format string consists of a format character followed by an optional precision specifier . Table 3-2 shows the available format characters. Table 3-2. Format Characters Format Character | Meaning | C | Currency (locale specific) | D | Decimal integer | E | Exponential (scientific) | F | Fixed point | G | General (E or F) | N | Number with embedded commas | X | Hexadecimal | Sample Formatting Code The sample program in Ira\Step1 provides an example. The header uses width specifiers, and the output inside the loop uses width specifiers and the currency format character. ... Console.WriteLine(_ "{0,4} {1,12} {2,12} {3,12}" , _ "Year", "Amount", "Interest", "Total") Dim i As Integer = 1 While i <= years interest = total * rate total += amount + interest Console.WriteLine(_ "{0 , -4} {1, 12:C} {2, 12:C} {3, 12:C}" , _ i, amount, interest, total) i += 1 End While ... Control Structures The preceding code fragment illustrates a While End While loop. VB.NET supports several control structures, including the If and Select decision statements as well as For and While loops . Most of these will be familiar to Visual Basic programmers. The Throw and Try statements are used in exception handling. We will discuss exceptions later in this chapter. The SyncLock statement can be used to enforce synchronization in multithreading situations. We will discuss multithreading in Chapter 10. Select Case Statement A Select Case statement is used to execute one of several groups of statements, depending on the value of a test expression. The test expression must be one of the following data types: Boolean , Byte , Char , Date , Double , Decimal , Integer , Long , Object , Short , Single , or String . After a particular case statement is executed, control automatically continues after the following End Select . The program SelectDemo illustrates use of the Select Case statement in VB.NET. ... Select Case (scores(i)) Case 1 Console.WriteLine("Very Low") Case 2 Console.WriteLine("Low") Case 3 Console.WriteLine("Medium") Case 4 To 5 Console.WriteLine("High") Case Else Console.WriteLine("Special Case") End Select ... Methods Our Ira\Step1 example program has a method IraTotal for computing the total IRA accumulation by use of a formula. In VB.NET, every function is a method of some class or module; there are no freestanding global functions. If a method does not refer to any instance variables of the class, the method can be declared as Shared . We will discuss instance data of a class later in this chapter. If a method is accessed only from within a single class, it may be designated as Private . Note the use of the Private keyword in the Ira\Step1 example. The Shared keyword is not used however, since the example uses a module instead of a class. All methods in a module are shared by default. Also in the Ira\Step1 example, note the use of the Pow and Round methods of the Math class, which is another class in the System namespace. These methods are shared methods. To call a shared method from outside the class in which it is defined, place the name of the class followed by a period before the method name. ... Private Function IraTotal (ByVal years As Integer, _ ByVal rate As Double, ByVal amount As Double) As Double Dim total As Double = _ amount * ( Math.Pow (1 + rate, years) - 1) / rate Dim total_in_cents As Long = _ Math.Round (total * 100) total = total_in_cents / 100 Return total End Function ... Console Input in VB.NET Our first Ira program is not too useful, because the data are hardcoded. To perform the calculation for different data, you would have to edit the source file and recompile. What we really want to do is allow the user of the program to enter the data at runtime. An easy, uniform way to do input for various data types is to read the data as a string and then convert it to the desired data type. Use the ReadLine method of the System.Console class to read in a string. Use the ToXxxx methods of the System.Convert class to convert the data to the type you need. This can be seen in the Ira\Step2 example. Console.Write("amount: ") Dim data As String = Console.ReadLine() amount = Convert.ToDecimal(data) Using Console Input to Pause We mentioned earlier in the chapter that if you run a Visual Studio console application under the debugger, the console window will close automatically when the program exits. If you want to keep the window open, you can place a ReadLine statement at the end of your Main procedure. The program HelloWithPause provides an illustration. Sub Main() Console.WriteLine("Hello, world") Console.Write("Press Enter to exit") Dim str As String = Console.ReadLine() End Sub | Although console input in VB.NET is fairly simple, we can make it even easier using object-oriented programming. We can encapsulate the details of input in an easy-to-use wrapper class, InputWrapper (which is not part of VB.NET or the .NET Framework class library, and was created for this book). Using the Inputwrapper Class In VB.NET, you instantiate a class by using the New keyword. Dim iw As InputWrapper = New InputWrapper() This code creates the object instance iw of the InputWrapper class. The InputWrapper class wraps interactive input for several basic data types. The supported data types are int , double , decimal , and string . Methods getInt , getDouble , getDecimal , and getString are provided to read those types from the command line. A prompt string is passed as an input parameter. The directory InputWrapper contains the files InputWrapper.vb , which implements the class, and TestInputWrapper.vb , which tests the class. (For convenience, we provide the file InputWrapper.vb in each project where we use it.) You can use the InputWrapper class without knowing its implementation. With such encapsulation, complex functionality can be hidden by an easy-to-use interface. (A listing of the InputWrapper class is in the next section.) Here is the code for Ira\Step2 . We read in the deposit amount, the interest rate, and the number of years, and we compute the IRA accumulation year by year. The first input is done directly, and then we use the InputWrapper class. The bolded code illustrates how to use the InputWrapper class. Instantiate an InputWrapper object iw by using new . Prompt for and obtain input data by calling the appropriate getXXX method. ' Ira.vb - Step 2 Imports System Module Ira Public Sub Main() Dim iw As InputWrapper = New InputWrapper() Dim amount As Decimal ' annual deposit amount Dim rate As Decimal ' interest rate Dim years As Integer ' number of years Dim total As Decimal ' total accumulation Dim interest As Decimal ' interest in a year Console.Write("amount: ") Dim data As String = Console.ReadLine() amount = Convert.ToDecimal(data) rate = iw.getDecimal("rate: ") years = iw.getInt("years: ") total = 0D Console.WriteLine(_ "{0,4} {1,12} {2,12} {3,12}", _ "Year", "Amount", "Interest", "Total") Dim i As Integer = 1 While i <= years interest = total * rate total += amount + interest Console.WriteLine(_ "{0, -4} {1, 12:C} {2, 12:C} {3, 12:C}", _ i, amount, interest, total) i += 1 End While Console.WriteLine(_ " Total using formula = {0}", _ IraTotal(years, rate, amount)) End Sub Private Function IraTotal(ByVal years As Integer, _ ByVal rate As Double, ByVal amount As Double) As Double Dim total As Double = _ amount * (Math.Pow(1 + rate, years) - 1) / rate Dim total_in_cents As Long = _ Math.Round(total * 100) total = total_in_cents / 100 Return total End Function End Module Inputwrapper Class Implementation The InputWrapper class is implemented in the file InputWrapper.vb . You should find the code reasonably intuitive, given what you already know about classes. ' InputWrapper.vb ' ' Class to wrap simple stream input ' Datatype supported: ' int ' double ' decimal ' string Imports System class InputWrapper Public Function getInt(ByVal prompt As String) _ As Integer Console.Write(prompt) Dim buf As String = Console.ReadLine() Return Convert.ToInt32(buf) End Function Public Function getDouble(ByVal prompt As String) _ As Double Console.Write(prompt) Dim buf As String = Console.ReadLine() Return Convert.ToDouble(buf) End Function Public Function getDecimal(ByVal prompt As String) _ As Decimal Console.Write(prompt) Dim buf As String = Console.ReadLine() Return Convert.ToDecimal(buf) End Function Public Function getString(ByVal prompt As String) _ As String Console.Write(prompt) Dim buf As String = Console.ReadLine() Return buf End Function End Class Note that, unlike the method IraTotal , the methods of the InputWrapper class are used outside of the class so they are marked as public . If bad input data is presented, an exception will be thrown. Exceptions are discussed in Chapter 5. |