Professional ASP.NET 1.1 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Professional ASP.NET 1.1 [Electronic resources] - نسخه متنی

Alex Homeret

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



Visual Basic .NET


The latest version of Visual Basic is a major leap forward in terms of functionality, with several features added to take advantage of the Common Language Specification (CLS) and the CLR.


Each generation of a language brings improvements. To understand why Visual Basic .NET implements the changes it does, consider for a moment some of the problems associated with previous versions of Visual Basic:



The Visual Basic runtime libraries:These are relatively large DLLs incorporating the base functionality, and are required for all Visual Basic programs to run. Common complaints concerned the size of these DLLs, and versioning problems (different libraries for different versions of VB). You might think that these have just been replaced by the CLR, but the CLR is much more than this, and addresses far more than just VB. While size may still be considered an issue, the redistributable CLR is around 18 MB and supports multiple versions.



Poor object-oriented features:Object-oriented programming gurus criticized Visual Basic for its lack of 'proper' functionality – not providing features such as inheritance, overloading, and so on. Although these are valid points, many of the problems really stemmed from the capabilities of COM rather than Visual Basic itself.



Inability to create multi-threaded applications:With the introduction of Microsoft Transaction Server (MTS), n-tier architecture became a reality, and Visual Basic programmers started to get to grips with componentization. However, Visual Basic components were forced into an Apartment Threading model, a limitation that attracted much criticism from programmers who wanted to build multi-threaded components. Personally, I think much of this condemnation is misplaced, as I wonder how many people could actually write a fully threaded component (I'm not sure I could). Think about it – managing the threads, state, and so on, isn't easy.



All of these problems disappear in Visual Basic .NET. The runtime libraries are no longer needed because they're taken care of by the CLR, and the object-oriented features have been massively improved (partly because of CLR and CLS support) and the whole threading issue has gone away. With the CLR, you just don't need to think about threading (unless you want to). Let's look at some of the new features in Visual Basic .NET.



Object-Oriented Features



The OO features were probably one of the enhancements most requested by programmers. I remember being at a Microsoft event when Visual Basic 6 was in beta, and the most frequently asked question was whether inheritance will be supported. Since this is an intrinsic feature of the CLR, it is now supported, and classes are inheritable by default. In fact, since everything in .NET is class based, you have an enormous amount of flexibility, as you can not only extend and overload your own classes, but many system ones too.


Classes


As in previous versions of Visual Basic, classes are created using the


Class statement. However, the syntax has changed a little:




[ Public | Private | Protected | Friend | Protected Friend ]


[Shadows]


[MustInherit | NotInheritable] Class className



End Class






Note


Visual Basic still requires the underscore (


_ ) for line continuation – to make things clearer, it's not shown in the preceding syntax outline.




Let's look at the keywords in more detail:




































Keyword




Description




Public




The class is publicly accessible.




Private




The class can only be accessed within the file in which it is declared.




Protected




The class is only accessible from the containing class or types derived from the containing class.




Friend




The class is only accessible from this assembly.




Protected Friend




The class is only accessible from this program or types derived from the containing class.




Shadows




The class shadows an identically named class in a base class.


Shadows is only available inside classes, structures, and interfaces.




MustInherit




This class is an abstract class, and the class members must be implemented by inheriting classes.




NotInheritable




This class is not inheritable.




Within a class, the member definition follows the same rules. Members that are not explicitly declared with a keyword are


Public by default.


For example:




Public Class Calculator



' implementation goes here



End Class



Or:




Protected MustInherit Class Calculator



' abstract implementation goes here



End Class



Methods



Methods are declared as a


Sub or a


Function , but there are improvements to fit in with the inheritance rules. The syntax for a


Sub is now:




[Overloads | Overrides | Overridable | NotOverridable | MustOverride |



Shadows | Shared]



[Private | Public | Protected | Friend | Protected Friend]



Sub subName [(parameters)]



End Sub



The syntax for a


Function is:




[Overloads | Overrides | Overridable | NotOverridable | MustOverride |



Shadows | Shared]



[Private | Public | Protected | Friend | Protected Friend]



Function functionName [(parameters)] [As type]



End Function



The various keywords are described in the following table:
















































Keyword




Description




Overloads




The member is overloaded, with more than one declaration existing, each with different parameters.


Overloads is not required when overloading methods in the same class, but if it is used, it must be used on all overloaded methods.




Overrides




The member overrides an identically named member from a base class. This is useful for sub-classing situations where you want to provide your own implementation of a particular member. The overridden method must have the same signature; that is, the parameters and data types must match those of the base class member.




NotOverridable




The member cannot be overridden in a derived class.




Overridable




The method can be overridden by a derived class.




MustOverride




The member must be overridden in a derived class. This implies


Overridable .




Shadows




The method shadows a method in a parent class. This means that the method in the parent class is not available, and allows creation of methods with a different signature (parameters & data types) than that of the parent. It effectively re-declares the type.




Shared




The member is shared by all instances of the class, and it exists independently of a class instance. This is equivalent to a static method in C# or C++.




Public




The member is publicly accessible.




Private




The member is only accessible within the class.




Protected




The member is only accessible from the containing class or types derived from the containing class.




Friend




The member is only accessible from this program.




Protected Friend




The member is only accessible from this program or types derived from the containing member.




For example:




Public Class Calculator


Public Function Add(Op1 As Double, Op2 As Double) As Double


Return Op1 + Op2


End Function


End Class







Note


This is an important change from previous function syntax – the value of the function is now returned using the


Return keyword, rather than by setting the function name to the value.




Properties



Properties can be implemented as


Public member variables or by using the


Property statement. For example:


Public Class Calculator


Public Op1 As Double


Public Op2 As Double
Public Function Add() As Double
Return Op1 + Op2
End Function
End Class



The class could be used in the following way:




Dim calc As New Calculator


calc.Op1 = 123


calc.Op2 = 456


Response.Write(calc.Add())



The preceding example uses public variables. The alternative (and preferred) approach is to use


Property , the syntax of which has changed as follows:




[Default | ReadOnly | WriteOnly] Property propertyName ([parameters])


[As type]


Get


' code for getting the property


End Get



Set


' code for setting the property


End Set



End Property



A property defined as


ReadOnly can only have the


Get block. Likewise, a property with only a


Get block must be marked as


ReadOnly . The same applies for


WriteOnly and the


Set block. There is also no longer a


Let option, as


Set provides the same functionality.


For example:


Public Class Calculator


Private _op1 As Double


Private _op2 As Double



Public Property Operand1() As Double


Get


Operand1 = _op1


End Get


Set


_op1 = value


End Set


End Property



Public Property Operand2() As Double


Get


Operand2 = _op2


End Get


Set


_op2 = value


End Set


End Property



End Class



Notice the use of the keyword


value in the


Set block. This is the actual code you should type, as


value is an implicit variable that contains the value of the property being set.


Default Properties and Property Parameters



Default properties are another area of change, as they are only supported on properties with a parameter list. Therefore, you could add a property called


Result to your


Calculator class, to contain the last result of an operation, but you wouldn't be able to make it the


Default property. Hence, you can't code it like this:




Default Property Result() As Double



This stops you doing the following:




Label1.Text = MyCalc



To declare a default property, you need to have parameters (and these cannot be declared as


ByRef ). For more details, consult the Visual Basic .NET documentation supplied with the .NET SDK.


Constructors and Object Creation



The


Class_Initialize event has been removed from classes, but has been replaced with a member function called


New , which enables you to inherit from constructors.


One of the cool new features of Visual Basic .NET is the use of overloading, which is perfect for providing constructors. The


New() method is a special case for overloading, since the


Overloads keyword is not required. For example, consider a


Person class:




Public Class Person



Private _firstName As String


Private _lastName As String



Sub New()


_firstName = ""


_lastName = ""


End Sub



Sub New(firstName As String, lastName As String)


_firstName = firstName


_lastName = lastName


End Sub



Public Property FirstName() As String


' property code here


End Property



Public Property LastName() As String


' property code here


End Property



End Class



In this example there are two occurrences of


Sub New() : one without parameters, and another with. This means you can write:




Dim coolDude As New Person()


coolDude.FirstName = "Vince"


coolDude.LastName = "Patel"



Or




Dim coolDude As New Person("Vince", "Patel")



This provides a richer way of using classes and simplifies code.


Destructors and Object Destruction



Like the


Class_Initialize() method,


Class_Terminate() has also been replaced by a


Destruct() method. For example:




Sub Destruct()



' code to clean up here



End Sub



There has been a big change in the way destructors are called from previous versions of Visual Basic, and it revolves around the CLR. One of the good features of the CLR is garbage collection (GC), which runs in the background collecting unused object references, freeing you from having to ensure that you always destroy them. However, the downside is that since it's a background task, you don't know exactly when your destructor is called.


During the time of the beta releases, there was a wide discussion regarding this, resulting in an extensive paper from Microsoft about garbage collection and its effects (search the MSDN Web site for Deterministic Finalization for more details). Some people were concerned that there might be cases where they would need to guarantee something happening (such as resource cleanup) when the object is no longer in use. If this is the case, then the advice is to create a method to house this functionality, and call this method when you have finished with the class instance.


In reality, the time difference between releasing the object instance, and it being garbage collected, is likely to be very small, since the garbage collector is always running.


Inheritance



As mentioned in the previous chapter, everything in .NET is an object, so you can inherit from pretty much anything. Consider the


Person class as a base class; you could create a new class from it in the following way:




Public Class Programmer


Inherits Person



Private _avgHoursSleepPerNight As Integer



Public Sub New()


MyBase.New()


End Sub


Public Sub New(firstName As String, lastName As String)


MyBase.New(firstName, lastName)


End Sub



Public Sub New(firstName As String, lastName As String, _


hoursSleep As Integer)


MyBase.New(firstName, lastName)


_avgHoursSleepPerNight = hoursSleep


End Sub



Public Property AvgHoursSleepPerNight() As Integer


Get


AvgHoursSleepPerNight = _avgHoursSleepPerNight


End Get


Set


_avgHoursSleepPerNight = value


End Set


End Property



End Class



This class extends the existing


Person class and adds a new property. Let's look at the way it does this.


First, after the class declarations comes the


Inherits statement, where the base class we are inheriting from is specified:


Public Class Programmer
Inherits Person


Next, come the definitions for the existing constructors. Our class provides an extra one, so we need to overload the base class constructors. Notice how the definitions of these match the definitions in the base class, and how we call the constructor of the base class using


MyBase . We are not changing the existing constructors, just adding our own, so we just want to map functionality to the base class:


Public Sub New()
MyBase.New()
End Sub
Public Sub New(firstName As String, lastName As String)
MyBase.New(firstName, lastName)
End Sub


Now we can add our extra constructor, which calls one of the previous constructors and then sets the additional property:


Public Sub New(firstName As String, lastName As String, _
hoursSleep As Integer)
MyBase.New(firstName, lastName)
_avgHoursSleepPerNight = hoursSleep
End Sub


Finally, we add the definition of the new property:


Public Property AvgHoursSleepPerNight() As Integer
Get
AvgHoursSleepPerNight = _avgHoursSleepPerNight
End Get
Set
_avgHoursSleepPerNight = value
End Set
End Property


In object-oriented terms, this is standard stuff, but it's new for Visual Basic and provides a great way to promote code reuse.


Classes and Interfaces



An interface is the description of the methods and properties a class will expose – it's an immutable contract with the outside world. The interface doesn't define any implementation – just the methods and properties. Derived classes then have to provide the actual implementation.


In Visual Basic .NET you automatically get a default interface that matches the class methods and properties, but there may be times when we want to explicitly define the interface. One good example of this is that when creating .NET-serviced components, the interface can be used to provide versioning features. See Chapter 23 for more details on this.


To create an interface, the


Interface construct is used as follows:




Public Interface IPerson


Property FirstName() As String


Property LastName() As String


Function FullName() As String


End Interface



As you can see, there is no implementation specified here. By convention, the interface name is the class name preceded by


I , although this isn't enforced. To derive a class from an interface, the


Implements keyword is used on the class:




Public Class Person


Implements IPerson



Private _firstName As String


Private _lastName As String



Public Property FirstName() As String Implements IPerson.FirstName


' implementation goes here


End Property



Public Property LastName() As String Implements IPerson.LastName


' implementation goes here


End Property



Public Function FullName() As String Implements IPerson.FullName


Return _firstName & " " & _lastName


End Function



End Class







Note


Both the class, and the methods and properties, have to specify their implementation interface.




Multiple inheritance is allowed only in an interface. For example:




Public Interface Person


Inherits IPerson


Inherits ICleverPerson


End Interface




Language Changes



Along with the object-oriented features, there have been many changes to the language. We won't go into exhaustive detail here (it's well covered in the documentation), but here are some things to watch out for:



Array bounds:The lower bound of an array is always


0 , and cannot be changed. The


Option Base statement is not supported.



Array declaration:


ReDim can only be used if the array has already been declared.



Array sizes:Arrays do not have a fixed size (although the number of dimensions is fixed). For example.




Dim ConnectionTimes(10) As Date



This defines an array with an initial size of 11 elements. Arrays can also be populated on declaration:




Dim ConnectionTimes() As Date = {"10:30", "11:30", "12:00", "06:00"}




String length:The fixed-width string is not supported unless the


VBFixedString attribute is used.



Variants:The


Variant data type is no longer supported, being replaced by a more generic


Object . The corresponding


VarType function is also not supported, as the


Object has a


GetType method.



Data types:The


Currency data type is replaced by


Decimal . The


Integer type is now 32 bits, with


Short being 16 bits and


Long being 64 bits.



Short cut operators:A new short form of addition and assignment has been added. For example.




counter += 1


name &= " Sussman"





Default properties:As mentioned earlier, default properties are not supported, unless they take parameters.



Variable declaration:When declaring multiple variables on the same line, a variable with no data type takes the type of the next declared type (and not


Variant as was the case in VB6). For example, in the following declarations


Age is an


Integer .




Dim Age, Hours As Integer


Dim Name As String, Age, Hours As Integer





Variable scope:Block scope is now supported, so variables declared within blocks (such as


If blocks) are only visible within the


If block. In Visual Basic 6, variables could be declared anywhere, but their scope was the entire method.



Object creation:The


As New keywords can be used freely on the variable declaration line. There is no implicit object creation, so objects that are


Nothing remain set to


Nothing unless an explicit instance is created.



Procedure parameters:The rules for parameter passing and optional parameters have changed. See the section on Parameters later for more information on this.



Procedure calls:Parentheses are now required on all procedure calls, not just functions.



Function return values:The return value from a function is now supplied with the


Return statement, rather than by setting the function name to the desired value.



While loops:The


Wend statement has been replaced with


End While .



String and Variant functions:The string manipulation functions that had two types of call (


Trim returned a


Variant and


Trim$ returned a


string ) are replaced with overloaded method calls.



Empty and Null:The


Empty and


Null keywords have their functionality replaced by


Nothing .



There are many other changes, some of which don't really affect ASP.NET programmers. For a full list, consult the Visual Basic .NET documentation, or see Wrox's Professional VB.NET, 2nd Edition, ISBN: 0-7645-4400-4.


References



Since you're freed from using a set design tool, some of the features you are used to now require a bit more typing. One example of this is referencing other components. In Visual Basic 6, to access COM components you select References from the Project menu. There's something similar in Visual Studio .NET to reference assemblies (or even COM components), but if you're using Notepad, you have to provide the reference yourself. This is done using the


Imports keyword. For example:




Imports System


Imports MyComponent



It's also possible to alias references using the following syntax:




Imports aliasName = Namespace



If an alias is used, the alias must be included in references to classes that the namespace contains. For example, if you have a namespace called


MyComponent containing a class called


MyClass , and import the namespace like this:




Imports foo = MyComponent



You can't then access the class like this:




Dim comp As MyClass



You have to use the following syntax:




Dim comp As foo.MyClass



Structured Exception Handling



One of the best new features of .NET is a unified structured exception-handling framework, which extends to Visual Basic .NET. Although


On Error is still supported, a far better way of handling errors is to use the new


Try …


Catch …


Finally structure. The way it works is simple, with each of the statements defining a block of code to be run.


The syntax is:




Try



' code block to run



[



Catch [exception [As type]] [When exception]



' code to run if the exception generated matches


' the exception and expression defined above



[Exit Try]


]


Catch [exception [As.type]] [When expression]


' code to run if the exception generated matches


' the exception and expression defined above



[Exit Try]



[Finally


' code that always runs, whether or not an exception


' was caught, unless Exit Try is called


]



End Try



This allows you to bracket a section of code and then handle generic or specific errors. For example:




Try


' connect to a database and


' retrieve some data


' ... code left out for clarity ...



Catch exSQL As SQLException


ErrorLabel.Text = "SQL Error: " & exSQL.ToString()



Catch ex As Exception


ErrorLabel.Text = "Other error: " & ex.ToString()



Finally


FinishedLabel.Text = "Finished"



End Try



You can have multiple


Catch blocks, to make our error handling specific to a particular error. Always put the most specific


Catch blocks first and the more generic ones last, as the


Catch blocks are tried in the order they are declared.


The


Throw statement can be used to throw your own errors, or even re-raise errors.


Errors and exceptions are covered in detail in Chapter 22.


Data Types and Structures



There are three new data types:



Char : for unsigned 16-bit values.



Short : for signed 16-bit integers. This is the equivalent to the current Visual Basic


Integer (in Visual Basic .NET the


Integer is now 32-bits and the


Long 64-bits).



Decimal : for signed integers.



Custom types are now provided by the


Structure statement, rather than the


Type statement. The syntax is:




[Public | Private | Friend] Structure structureName


End Structure



For example:




Public Structure Person


Public FirstName As String


Public LastName As String


Private Age As Integer


End Structure



The use of structures is unified with classes, enabling structures to not only contain member variables, but also methods:




Public Structure Narcissist


Public FirstName As String


Public LastName As String


Private RealAge As Integer



Public Function Age() As Integer


Return RealAge – 5


End Function


End Structure



Whether you use classes or structures is purely a coding and design decision, but the close linking of the two types provides added flexibility.


Parameters



Several things have changed regarding passing parameters to procedures. The most important is that parameters now default to


ByVal . To achieve reference parameters, you must explicitly put


ByRef in front of the parameter name.


Secondly, as mentioned earlier, all method calls with parameters must be surrounded by parentheses. The previous versions of Visual Basic had the inconsistency that parentheses were required for functions but not subroutines. For example, the following is no longer valid:




MyMethod 1, 2, "foo"



Instead, you must use:




MyMethod(1, 2, "foo")



For optional parameters, you now have to specify a default, and the


IsMissing() method is removed. For example, you cannot write:




Sub MyMethod(Name As String, Optional Age As Integer)



If IsMissing(Age) Then


...



You have to supply a default:




Sub MyMethod(Name As String, Optional Age As Integer = -1)



Debugging and Message Boxes



Although not relevant to ASP.NET pages, there are two things that might hit you if you are using Visual Studio .NET:



The


Print method of the


Debug object has been replaced by four methods –


Write() ,


WriteIf() ,


WriteLine() , and


WriteLineIf() .



The


MsgBox statement has been replaced with the


Show method of the


MessageBox object.



Debugging is covered in detail in Chapter 22.


Backward Compatibility



To ease the transition from Visual Basic 6 to Visual Basic .NET, you can reference the


Microsoft.VisualBasic.Compatibility.VB6 namespace, which provides access to much of the removed or changed functionality. It's probably best not to overuse these compatibility features, though. The changes to the language have been made not only to improve it, but also to bring it in line with the CLS and the other .NET languages.


/ 244