The .NET Framework, an environment for developing, deploying, and running .NET applications, consists of three basic parts: ASP.NET, the Common Language Runtime (CLR), and the .NET Framework classes. Much has been written about ASP.NET and the CLR, but comparatively little has been written about the .NET Framework classes. This first of a two-part series on the subject lays the groundwork for working with the System classes and introduces a couple of useful classes: the System.Math and System.Random classes. In the second part of this series, I will discuss additional classes that you can take advantage of in your ASP.NET applications.
The .NET Framework classes (or the System classes) provide a huge amount of core functionality that Microsoft has made available and that you can take advantage of when building ASP.NET (and non-ASP.NET) applications. The System classes are available to developers of all .NET languages. Think of the System classes as the Windows API of .NET. Unlike the Windows API, however, the System classes provide high-level COM-like interfaces that are fairly easy to employ.
Classes, Assemblies, and Namespaces
Like all .NET classes, the System classes live within assemblies. The .NET assembly is the equivalent of the COM DLL or EXE file--It represents the executable file that holds the class. For example, the Math class and its properties and methods are located within the mscorlib.dll assembly. There are two types of assemblies in .NET -- private and shared. Private assemblies are ones that can be used in a single application and are typically located in an application's bin folder. In contrast, shared assemblies can be used across applications and must be loaded into the global assembly cache (the .NET equivalent of the system registry) by the assembly's creator. The .NET System classes are all shared assemblies.
If you've ever done any Windows API programming, you know one of the problems with the Windows API is identifying and finding the function you need to call. Within a particular Windows API DLL, there is no way to organize the functions. It's as if all of the API calls were thrown into one huge DLL toy box upon creation. Fortunately, the .NET classes are organized logically into hierarchies called namespaces. For example, the Math class is a member of the System namespace. Namespaces can be nested several levels deep within the hierarchy. For example, the ADOConnection class is a member of the System.Data.ADO class.
Referencing Members of a Namespace
In order to use a class in a namespace, you must be able to work your way down the namespace hierarchy to locate the particular class you want to use. You do this by explicitly referencing a class using the complete dot-separated name. For example, to create an ADOConnection object you might use code like this (this example and the other examples in this article are written using Visual Basic, but the basic concepts are the same, regardless of which .NET language is used):
Dim cnx As System.Data.SQL.SQLConnection
cnx = New System.Data.SQL.SQLConnection( _
"server=(local);uid=sa;pwd=;database=pubs")
Alternately, you can use an Import directive to make your life a little easier and reduce the chances of developing repetitive strain injuries. For example, the following code tells ASP.NET to import the System.Data.SQL namespace into the page:
<%@ Import Namespace="System.Data.SQL" %>
Once you've imported a namespace, you can simplify your class references by dropping everything that comes before the class name. The ADOConnection object code now becomes:
Dim cnx As SQLConnection
cnx = New SQLConnection("server=(local);uid=sa;pwd=;database=pubs")
Using the Import directive can save you a lot of typing!
A number of namespaces are automatically imported by ASP.NET and thus you don't need to import these namespaces into your pages to take advantage of the namespace shortcuts for these classes:
System
System.Collections
System.Text
System.Text.RegularExpressions
System.Web
System.Web.Caching
System.Web.SessionState
System.Web.Security
System.Web.UI
System.Web.UI.WebControls
System.Web.UI.HtmlControls
It's important to realize that importing a particular high-level namespace does not import namespaces below it in the hierarchy. Thus, the following Import directive imports only classes in the System.Data namespace and does not import classes from the System.Data.ADO, System.Data.SQL, and other namespaces that sit below the System.Data namespace:
<%@ Import Namespace="System.Data" %>
Classes Have Members
Classes contain members -- the properties, methods, fields, events, and constructors that make up a class. A property is an attribute of a class. For example, the System.Array class has a property named Length. A method is an action that the class knows how to perform. You can sort an array using the Array class' Sort method. A field is similar to a property and for all practical purposes can be treated as a property. The Math class' PI field returns the value of pi. An event represents something you can react to. The ADOConnection class has an event named InfoMessage that occurs when the provider sends a warning or an informational message. Finally, a constructor is a special type of method that is called when you create a new object. For example, when you create a new SQLConnection object you call its constructor, passing it a connection string.
Members can be of two basic types -- static or instance. Static members (also known as shared members) are shared across all instances of a class and do not require you to work with a specific instance of the class. To use a static member, you simply refer to the member using the class name as if it were the name of the object. For example, the Pow method of the System.Math class is a static member. Using this method you can raise a number to a power. The following code raises the number 5 to the 3rd power:
answer = Math.Pow(5, 3)
In contrast to static members, instance members work on a specific instance of an object, which means that you must first create the object instance before you can use an instance member. For example, you can use the NextDouble method of the System.Random class, an instance member, to return a random number. The following code sets the dblRandom variable to a random number using a System.Random object:
Dim dblRandom As Double
Dim rnd As Random = New Random
dblRandom = rnd.NextDouble
VB.NET Functions versus System Class Members
The VB.NET language has a long and sorted history. While Microsoft has removed some legacy functionality, there remain a number of VB.NET language features that overlap the functionality of the System classes. When given the choice, it's almost always a better idea to use the System classes rather than legacy VB.NET functionality. Using the System classes makes code more portable to other languages and better suited for future versions of VB.NET, in which Microsoft may remove some older legacy functionality.
Making Calculations Using the System.Math Class
The System.Math class contains a number of fields and methods you can use to perform mathematical calculations. All of System.Math's members are static.
The Pow method of System.Math can be used to raise a number to a power. For example, use Pow and the Math.PI field to calculate the area of a circle like so (where dblRadius is set to the radius of a circle):
dblArea = Math.PI * Math.Pow(dblRadius, 2)
Math.PI returns the value of pi, the ratio of a circle's circumference to its diameter.
Use the Sqrt method to return the square root of a number. For example, the following code calculates the square root of 64:
answer = Math.Sqrt(64)
Use the Abs method to return the absolute value of a number, the value of a number disregarding its sign. For example, the following code returns the absolute value of the number -7.8:
answer = Math.Abs(-7.8)
In this case, answer would be 7.8. The Sign method can be used to return the sign of a number. If the number is negative, Sign returns -1; if it's positive, Sign returns 1; and if the number is equal to 0, sign returns 0.
The Round method rounds a number to the nearest whole number. For example, the following code is used to round the number 3.4677789:
answer = Math.Round(3.4677789)
In this case, the answer would be 3. If you use Round to round a number that is exactly halfway between two numbers (for example, 3.5), then Round always returns the even number closest to the number. Thus, in this case, Math.Round(3.5) would be 4. However, Math.Round(6.5) would return 6.
The Floor method is used to truncate a real number. Floor actually returns the largest whole number smaller than the original number. For example, use the following to return the floor of 5.9:
answer = Math.Floor(5.9)
In this case, the answer would be 5. Note that the Floor method may behave differently than you might expect for negative values. For example, Math.Floor(-5.9) returns -6.
The Math class contains a number of additional methods for making trigonometric and logarithmic calculations.
Generating Random Numbers Using the System.Random Class
The System.Random class is used to draw a random number. Unlike VB's Rnd function, however, System.Random can return both decimal and whole random numbers. Also, unlike Rnd, System.Random automatically seeds its random number generator with a random value derived from the date and time.
Use the NextDouble method of System.Random to return a Double random number between 0 and 1. The Next method returns an Integer random number between two Integer values. NextDouble and Next are both instance methods so you must instantiate a System.Random object before using these methods. The following complete ASP.NET page illustrates the use of these methods to generate 20 random numbers, 10 between 0 and 1 and an additional 10 between 1 and 50:
<%@ Page Language="vb" Explicit="True"%>
<head>
<title>15Seconds System.Random Example</title>
<script language="VB" runat="server">
Sub Page_Load(Src as Object, E as EventArgs)
' The .NET Framework way to get the
' equivalent of the VB6 Rnd function.
Dim rnd As System.Random = New System.Random
Dim i As Integer
lblOutput.Text &= "<table border=""1"">"
lblOutput.Text &= "<tr><th>rnd.NextDouble</th>" & _
<th>Next(1,50)</th></tr>"
For i = 1 To 10
lblOutput.Text &= "<tr>"
lblOutput.Text &= "<td>" & rnd.NextDouble & "</td>"
lblOutput.Text &= "<td>" & rnd.Next(1,50) & "</td>"
lblOutput.Text &= "</tr>"
Next
lblOutput.Text &= "</table>"
End Sub
</script>
</head>
<body>
<asp:label id="lblOutput" runat="server" />
</body>
</html>
The output generated by this page is shown in the following figure. (Of course, if you run this code, you will likely get a different set of random numbers.)
Summary
The .NET Framework provides a wealth of functionality that is built into a number of System classes. This article describes how .NET Framework assemblies, namespaces, and classes fit together and how to take advantage of the built-in System classes to perform mathematical calculations and generate random numbers. I've only scratched the surface of the functionality of the System classes, however. In part 2 of this two-part article, I will discuss several additional classes that I have found useful, including the Array, String, and DateTime classes. In the meantime, your best resource for investigating the .NET Framework in general and the System classes in particular is the .NET Framework SDK Documentation Help file that is part of the .NET Framework SDK (see http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml to download the .NET Framework and ASP.NET beta).
Additional Information
For more information, see the following from Microsoft:
Paul Litwin is the CEO of Litwin Consulting. He is the author of numerous articles and several books, including the Access 2000 Developer's Handbook. Paul is currently working on the book ASP.NET for Developers with coauthor Mike Amundsen. He travels the United States training developers and has authored courseware for AppDev's Active Server Pages, Visual InterDev, and Access classes, and CD and video seminars. Paul is a regular speaker at industry conferences and is the Conference Chair for the ASP Connections conference. He can be reached at plitwin@mcwtech.com.
In this article, Thiru Thangarathinam demonstrates the different classes and features available through the My namespace. By providing a speed-dial that allows you to more quickly and effectively utilize .NET framework functionalities in your application, the My feature provides huge productivity improvements for .NET developers. [Read This Article][Top]
Thiru Thangarathinam discusses taking advantage of the integation between
the .NET CLR and SQL Server 2005 in order to do things like create triggers
using managed code. [Read This Article][Top]
Developers often use brute force coding to marshal data between the GUI and application objects. In this article, Luther Stanton explains how to use .NET's out-of-the box data-binding functionality to make this job much easier. [Read This Article][Top]
Ambrose Little provides the complete source code for his 'Perfect Service'
and explains how the .NET Service Manager enables features such as drag-n-drop deployment. [Read This Article][Top]
There is broad-reaching debate about remoting, Web services, Enterprise Services, and DCOM. In short, it is a debate about the best technology to use when implementing client/server communication in .NET. Rocky Lhotka shares his thoughts on the issue while offering clear explanations of basic application architecture terminology. [Read This Article][Top]
This article provides and excellent foundation for COM Interop. It reviews COM's background, explains how VB6 interacts with COM, and then shows how to design .NET components to smoothly interact with COM. [Read This Article][Top]
The first article in this two-part series shows how to get Ambrose Little's .NET Service Manager running and then how to add plug-n-play services to it using drag-n-drop or XCOPY. [Read This Article][Top]
Although generics are extremely useful, they also seem to have a certain mystique that cannot be readily explained. This article hopes to remove that aura of mystery by showing just how easy it is to use generics and how useful they can be in many common situations. [Read This Article][Top]
When implementing custom components that require access to restricted resources, implicit impersonation must be used. Jay Nathan shows how to create a class that makes using .NET Impersonation a snap. [Read This Article][Top]
Tony Arslan shows how to use VS .NET's custom deployment feature to create configuration files on the target machine during installation. [Read This Article][Top]
Mailing List
Want to receive email when the next article is published? Just Click Here to sign up.