Introduction
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.
Additional Information
For more information, see the following from Microsoft:
By Paul Litwin