Dr. GUI .NET 1.1 #0

 

Revised for Version 1.1 of the Microsoft .NET Framework

April 24, 2003

Summary: Dr. GUI introduces the .NET Framework, Visual Basic .NET, and C# after explaining why the .NET Framework is interesting to programmers. The good doctor then shows "Hello World!" programs in Visual Basic .NET, C#, and ASP.NET, and shows how to do a swap function in the .NET Framework. Finally, Dr. GUI shows the IL and metadata of a couple of programs so you can see "under the hood" of the Framework. (50 printed pages)

Contents

Dr. GUI .NET Is Back...
What's .NET?
Dr. GUI's Take on the .NET Framework
Why Learn the .NET Framework?
What Will We Be Discussing?
Installation Notes
Writing Programs for .NET
Hello World .NET in C# and Visual Basic .NET
Swap Using ASP.NET
Give It a Shot!
Join Us!
Where to Learn More
What We've Done; What's Next

View the listing file source code that accompanies this article.

Dr. GUI .NET Is Back...

Those of you who were regular readers of Dr. GUI's tutorial series may have missed the good doctor—he's been on leave recently. But now he's back ... and the Dr. GUI .NET column is going to be better than ever.

After various machinations, Dr. GUI is now revising the articles to correspond to the final Version 1.1 release of the Microsoft® .NET Framework and Microsoft Visual Studio® .NET 2003. The revised series uses C# and Microsoft® Visual Basic® .NET in client applications, and Visual Basic .NET in Microsoft® ASP.NET applications.

So the good doctor's got the same old mission, but now the mission is renewed. It's to help you learn, no matter what kind of programming you do now, about the .NET Framework and how to use it to your best advantage.

Why Should I Read Dr. GUI .NET?

Before you read much farther, it would be helpful to take a look at what this column will be about, who's likely to benefit from it, and how.

Simply put: Dr. GUI .NET is about learning how to program for the .NET Framework. Whether you choose to use C# or Visual Basic .NET, you'll find the articles and code are written in your language. (Dr. GUI apologizes in advance if you use Microsoft JScript® .NET or C++. There are only so many hours in a day.)

So if you're a C, C++, C#, or Microsoft Visual J++® programmer (or a programmer using the language whose name begins with "J," from now on referred to as "Brand J"), you'll want to learn about the .NET Framework using C#. Read on. And if you're a Visual Basic programmer, you'll get what you need right here.

And because the examples are in both languages, everybody will get to learn a little about the other language—a good thing, since the perennial Language Debates will never be settled, so lots of code will be written in both languages. (Dr. GUI suspects that being bilingual or multilingual will be worth a nice raise.)

But wait ... there's more! In addition to console applications, we'll also be doing all the examples as ASP.NET applications. They won't be great ASP.NET applications, and you won't learn how to be a great ASP.NET programmer here (for that, see https://asp.net/). But you'll be able, if you're an ASP or ASP.NET programmer, to see how the richness of the .NET Framework can make your programming easier and more productive—and become a better programmer as a result.

If you're not an ASP.NET programmer, you'll have the opportunity to learn a little bit about ASP.NET programming and perhaps be inspired to learn more elsewhere and do some more advanced programming using ASP.NET. Dr. GUI has really enjoyed learning about ASP.NET programming to write this column, and he's looking forward to doing more—ASP.NET really makes Web programming easy for folks who aren't currently doing Web programming. ASP.NET makes it easy and fun because it's familiar.

For simplicity's sake, most of our ASP.NET applications will be in Visual Basic .NET after this column. Dr. GUI again apologizes in advance to folks who like to use C#, but notes that it'll be pretty easy to translate the C# console examples to ASP.NET—especially since you'll have the Visual Basic .NET console application and the Visual Basic .NET ASP.NET example as a guide in every case. (View the listing file source code that accompanies this article.)

Who should read Dr. GUI .NET?

So who should read Dr. GUI .NET? Well, anyone who wants to program for the .NET platform, including C#, C, C++, Visual J++, Brand J, and Visual Basic programmers, as well as folks who use whatever language for ASP and ASP.NET. And what will you learn? You'll learn a little about how the .NET Framework is put together, a little about how it works, and a lot about how to write effective programs using it, regardless of what kind of applications you write.

Not everything to everybody, though

Dr. GUI .NET can't be everything to everybody. If you're looking to learn certain things, such as advanced ASP.NET application development and database access techniques, you'll have to look elsewhere. Thankfully, there are many good sources of information—one of the best places to start looking is at https://asp.net/.

So Why Dr. GUI .NET?

Those of you who follow "Ask Dr. GUI" and the older versions of Dr. GUI .NET know that Dr. GUI is very excited about Microsoft .NET, even though he isn't always 100 percent sure what all's included in .NET and what's not at any given time. (If you want to find out, check out the official .NET Web site.) All the naming confusion reminds the good doctor of the Microsoft ActiveX® days—where marketing is involved, there's naming confusion. Dr. GUI's favorite was the short-lived insistence that the "X" in "ActiveX" was supposed to be silent. The equivalent in the .NET world is whether there's a space in front of the "dot" or not. The rule, as least as Dr. GUI understands it, is that there is for products, such as Visual Studio .NET, but not for technologies, such as ASP.NET. (Dr. GUI doesn't even want to know why.)

Regardless of whether the good doctor gets exactly what's part of .NET and what's not, and how much that'll change over the next few years, he does understand the key part that's important for developers: the .NET Framework. Not only does he "get" this part, he's very excited about it—it will make development more fun and productive. And while the .NET Framework will improve over the coming years, it's not going away any time soon.

Get .NET

You can get the .NET Framework 1.1, with or without Visual Studio .NET, now. And if you're writing ASP.NET applications, there's a technology preview of a new free IDE called Web Matrix you can try out now.

.NET Framework: Free!

The .NET Framework itself, including compilers, is free. You can find the .NET Framework SDK and redistributables at .NET Framework Downloads. From that URL, you can also download the redistributable parts that you (and your customers) need to run .NET Framework applications. Both are free.

Web Matrix: Free!

Visual Studio, discussed below, is a great tool for writing a variety of applications—both using the .NET Framework and regular native code in C/C++.

If you're only writing ASP.NET applications, however, you might want to try Web Matrix. It's a technology preview (version 0.5) of a community-supported IDE for building ASP.NET Web applications. It doesn't have Intellisense nor a debugger, and it relies on MSDN Online for the help system instead of installing its own faster help system with index. So Visual Studio is still well worth the money. On the other hand, the download is only 1.2 MB, and it's free, so why not try it? You can find it at https://asp.net/webmatrix.

Visual Studio: Not free, but worth every penny!

Although you can develop for the .NET Framework for free, Dr. GUI heartily recommends getting Visual Studio .NET Professional Edition (or higher), or at least one of the single-language Standard Editions, such as Microsoft Visual C#™ .NET. The Standard Editions are an incredible deal at a suggested retail of US$109.

If you're an MSDN subscriber, you should receive your copy of Visual Studio .NET soon, if you haven't already. You can also get it as a (huge!) download at MSDN Subscriptions. (Getting an MSDN subscription is one of the best ways to get Visual Studio .NET and all the rest of the things you need to develop for Microsoft® Windows®.) If you're not an MSDN Professional, Enterprise, or Universal subscriber, you can buy Visual Studio .NET or one of the single-language Standard Editions at your favorite software retailer. Check it out at the Visual Studio .NET site. The single-language Standard Editions are listed under the "Developer Tools" link.

And if you're a C++/MFC kind of guy like Dr. GUI, you'll be especially amazed at how easy and fun the combination of Visual Studio .NET and ASP.NET Web Forms make it to build Web applications. Dr. GUI had tried to avoid writing Web applications in the past because of the hassles of setting up a Web server, the complication of the request/response programming model and writing in mixed HTML and script, and the limitations of the scripting languages available. But Visual Studio .NET sets up the application in the Web server for you, the control/event model makes programming Web Forms as easy as writing Visual Basic code (and without writing HTML unless you want to), and since the programming languages are the exact same languages used for all .NET Framework applications, you have standard powerful languages with an incredibly rich class library at your disposal. In other words, Web programming is now as fun and easy as writing MFC or Visual Basic applications.

If you're an ASP programmer, you'll be amazed at how easy Web Forms are, and how simple it is to write Web pages that work well across different types of browsers. As you learn the .NET Framework, you'll come to appreciate the incredible power the Framework puts at your fingertips.

But what if you use C/C++ to write native-code applications? Is there anything in Visual Studio .NET 2003 for you? You bet there is. First off, you can get tighter, faster code by just recompiling. But the C++ compiler is also MUCH more standards conforming than ever before, which will make it easier to port code to and from other compilers and allow you to use libraries you couldn't use before. You can learn more about it at What's New in Visual C++ .NET 2003.

We're going to skip using Visual Studio and Web Matrix—just for this column—so that you can learn to do for yourself what Visual Studio and/or Web Matrix does for you, but we'll be using them in the future, because it's SO much easier.

What's .NET?

As we've just discussed, putting your finger on exactly what .NET is and isn't at any point in time is hard. But if you understand some of the key motivating forces behind .NET, it makes it a lot easier to get an idea of what it is.

How the World Has Changed

Consider some of the trends in our industry. Many folks are moving from using isolated PCs to using both PCs and a plethora of devices connected to multiple applications simultaneously via the Internet, wired and wireless, baseband and broadband. They're starting to expect their important information to be available wherever they go, on whatever device they use, in a form appropriate for that device. And since information is available over the Internet, they'd like to be able to combine raw data from multiple sources into meaningful information. Finally, they expect to be able to use software without the hassles of installation and upgrades—and they expect this to be much more reliable than PCs have ever been in the past.

And that's just the changes on client machines. The Internet has caused server-based applications to become much more popular than ever before and has made the connectionless request/response programming model common. But communicating between servers—especially among those running on different platforms—is difficult, as is handling the differences between various browsers and versions of browsers, not to mention all the different types of wireless devices. And because most substantial Internet applications are database-centric, the ability to access a wide variety of data sources easily is more important than ever.

How .NET Helps

The .NET Framework helps make these kinds of problems easier to solve. For instance, the.NET Compact Framework (for devices) ships with Visual Studio .NET 2003, so you can take advantage of the great common language runtime in .NET on a wide variety of devices, not just PCs.

.NET is designed from the ground up to work well with the Internet by embracing Internet standards, including supporting XML Web services so programs can use XML to easily get data from multiple sites and facilitate data interchange between different computer systems. .NET also makes accessing your data easier, and makes it far easier to write Web applications that will run well on a wide variety of browsers and devices without having to rewrite the application for each one. Finally, the .NET runtime supports simplified and reliable installation and upgrading for ease of use and increased reliability. That and the .NET runtime's security and versioning features also increase reliability and enable software to be sold as a service rather than a product.

Using XML Web services to integrate data from multiple sources into information you can use

Another important trend is that applications are integrating information from many sources in order to do something interesting. The canonical example is planning a business trip: You need an airplane ticket, rental car, and hotel. You'll want to shop for the deal that best meets your needs for each of these pieces, so you need data from three groups of different companies. Yet your trip also needs to be coordinated so that you arrive on time, have a car and hotel room (with broadband, of course) when you arrive, and can get home in a timely fashion. XML Web services using SOAP and standard XML Schema help applications communicate over the Internet in an industry-standard way so your application can use and share information with other computers, regardless of what platform the other computer is using. And the .NET Framework makes it almost trivial to write and use Web services. But if you'd like to see a decidedly non-trivial example of a real Web service implemented with .NET, check out http://terraserver.microsoft.NET/, which exposes map and aerial photograph information from around the world, courtesy of the Microsoft TerraService project, as well as additional information such as United States Census data.

And, last but not least, Microsoft and other companies will be providing interesting functionality as XML Web services that you can use as you would a local object. Using OPWS (Other People's Web services, a variation of SEC: Someone Else's Code) is always a good thing, assuming you get the functionality you need at a price you can afford.

So, the .NET Framework will make it easier to write new types of applications—applications that are easier to install and more reliable than ever before. And these applications will be powerful because they'll be able to take advantage of XML Web services provided by Microsoft and others—maybe you!

Dr. GUI's Take on the .NET Framework

A Brief History of Microsoft Operating System API Sets

Programming using the .NET Framework is different from using the Microsoft Win32® API, just as programming for Windows is very different from programming for DOS. Each of these APIs is a product of its times: the early '80s for DOS, the mid-'80s for Windows, and the late '90s for .NET.

DOS

The DOS API conceptually dates back to the designs of various single-tasking operating systems for small computer systems. Although operating systems such as UNIX and VMS were popular on minicomputers at the time microcomputers first arrived, microcomputers didn't have sufficient memory or speed to run these relatively sophisticated operating systems. As a result of extremely constrained memory and speed, operating systems such as DOS were primarily written in assembly language so they could be as fast and small as possible. The API for DOS was primarily a set of software interrupt calls (you remember INT 21h, don't you?) that you absolutely needed assembly language to call (perhaps by using a runtime library written at least partially in assembly language), and the small number (a few score) of services provided were mostly oriented to disk and character mode I/O. DOS only supported single tasking (and therefore only a single thread of execution), and DOS programs kept control of the computer system at all times, polling in a loop to see if keyboard input was ready when it wasn't doing something else.

Windows

The Windows API was designed in the early '80s—at a time when Reagan was President and C was the language of choice of most systems programmers. (Some significant systems were also written in Pascal, which is pretty similar to C in capabilities.) Stroustrup's seminal The C++ Programming Language wouldn't be published until 1986. "Structured programming" was the rage at the time, as programmers learned to eschew goto, and object-oriented programming (OOP) wouldn't become mainstream until the following decade.

As a result, the Win32 API was an API only a C (or Pascal) programmer could love. There was but one namespace, so all the hundreds (and later thousands) of API names were long, and API writers came up with various naming conventions to categorize them. Languages didn't directly support abstract data types, so programmers came up with naming schemes such as Microsoft's (from Charles Simonyi's) Hungarian scheme, which prefixed identifiers with an abbreviation representing the abstract type of the variable (such as "i" for index or "c" for count—both of which used the underlying language type "int").

But the most important difference in Windows was that, to take advantage of the graphical user interface, you had to totally restructure your program. Because Windows supported multitasking (although not multithreading in Win16), your program needed to give control back to the operating system when it wasn't doing anything. So instead of your program keeping control at all times, it was restructured as a set of message handlers, each of which quickly responded to a message (such as a mouse click, keystroke, or menu selection) from the operating system and returned to the operating system as soon as possible so your application could wait for the next message. In exchange for restructuring your application, you got to take advantage of rich Windows features such as device independence, support for dynamic link libraries and multitasking, and powerful standardized user interface functionality such as windows, dialog boxes, controls (such as buttons, list boxes, and edit controls), and menus.

Object-oriented programming

During the early '90s, object-oriented programming became popular. With object-oriented programming, it was possible to write larger projects with better-defined interactions between objects in the program and fewer undefined interactions. And objects allowed programmers a powerful way to create abstractions that made programming higher-level than before.

Visual Basic® encapsulated much of the message-routing logic in its runtime and gave programmers an object-based way to do Windows programming by allowing Visual Basic programmers to concentrate on writing message handling functions. As C++ became popular, class libraries such as MFC allowed programmers to write their Windows applications as groups of interacting objects, with many of the default interactions provided by an applications framework.

Yet the API underlying Visual Basic and MFC programs was still the good ol' Windows API designed before object-oriented programming became widespread. (To be fair, it should be noted that Windows does in fact embody some object-oriented concepts.) But the size of the Visual Basic and MFC runtime libraries testified to the fact that it took more and more effort to bridge the gap between object-oriented programming and the old, flat API set.

Components

In the mid-'90s, a new concept became popular: Software could be constructed of interchangeable components, much as one could assemble an audio system or home theater from a set of components. The idea is that by carefully defining interfaces and implementing them according to well-defined contracts, you could mix and match software components with relative ease.

Supporting component-based programming required significant additions to flat API sets—in Windows, OLE, and COM. Some of these additions were very complicated, because the C-based APIs were never intended to support operations such as dynamic creation of software objects and automatic lifetime management of objects—not to mention that C and C++ were intended for writing monolithic applications, not applications consisting of a set of components.

As a result, writing components was tedious and required files and translators to make up for the fact that the languages didn't really support component-based programming. While Visual Basic and libraries such as ATL relieved some of the tedium, many advanced (but interesting) operations were still quite hard. And new versions of components often caused existing applications to break due to a lack of support in Windows for flexible versioning policies.

So much functionality, so little in common

Finally, the fact that various APIs were added to Windows over the years led to huge inconsistencies in the programming model. Even the original Windows API had some bad inconsistencies—look at how differently windows, menus, and controls are handled compared with device contexts, pens, fonts, and brushes. But the more serious issue is that there are probably a half-dozen different ways of handling errors in Windows. (Maybe more—Dr. GUI hasn't counted.) There are probably a half-dozen character string types. And that's just the tip of the iceberg.

Clearly, between the hodgepodge of API programming models and the need to provide great support for component-based programs and Internet programming, the time is ripe for a new, cleanly designed, consistent, and modern API. Microsoft's answer to these issues is the .NET Framework.

A Fresh Start Without Starting Over: the .NET Runtime

Just as it was time in the late '80s to make a break with the old DOS ways of writing programs (What? Give up my TSRs?), it's now time for Windows programmers to start making a break from using the flat, old-fashioned Windows API in favor of a modern, object-oriented, component-based API. Dr. GUI recommends you use the .NET Framework and runtime so you can enjoy the benefits of a modern runtime.

Component-based to the core

To understand the .NET runtime, you must understand this: The .NET runtime is designed to give first-class support for modern component-based programming—directly in the runtime. In other words, it's all about components. If you understand this, understanding why the .NET runtime is designed as it is becomes much easier.

Just as Windows added direct support for windows, controls, drawing, and menus, as well as the infrastructure for message-based programming and abstractions to support device independence, the .NET runtime directly supports components (including properties and events), objects, inheritance, polymorphism, and interfaces.

Multilanguage, interoperates with legacy code!

And it provides this support while allowing you to use any of more than 20 different programming languages while still interacting with non-.NET code, whether running on your computer or on a different computer. In other words, .NET represents a fresh, modern start without having to start over: You can use a wide variety of languages, ranging from familiar to exotic, and keep using your old components and DLLs without modification. You can even use .NET components as you would any COM object—so your new .NET code can be used with old COM applications. (You might want to compare this language flexibility and ease of interoperation with legacy code with other runtime systems on the market, particularly Brand J.)

New features to support components

The other major features of interest in the .NET runtime are designed to give first-class support for component development. Direct support for properties and events makes component-based programming easy, without needing special interfaces and adapter design patterns. Automatic memory management deals with tricky object lifetime issues by allowing you to allocate objects and pass them between components without having to worry about which component is responsible for freeing the object when it's no longer needed. Serialization support enables "freeze-drying" components in a wide variety of formats, including industry-standard XML-based SOAP (not just a proprietary binary format), and reconstituting them later. The ability to call and create industry-standard XML Web services allows you to expose components to anyone using any device anywhere on the Internet, and to use components from any device anywhere on the Internet. Exceptions provide a robust, consistent way of handling error conditions. The fact that each code module has built-in complete metadata means that functionality like dynamic creation and method invocation becomes easy—and type-safe. (Heck, the .NET Framework even allows you to create and execute code on the fly!) And you can control which versions of components your application uses, making your applications more reliable. Finally, the fact that the code is in a processor-independent and easy-to-verify intermediate language (IL), rather than some particular machine language, means not only that your components can run on a variety of computers, but also that you can be sure your components won't overwrite memory they don't own and potentially cause a crash.

Each of these key features is in the .NET runtime so that it's easy to write robust object-oriented components.

But wait ... there's more!

In addition to all of the great component support features provided by the .NET runtime, the .NET Framework includes a huge number of classes designed to provide the infrastructure to solve today's programming problems—including sophisticated component-based Web server application support that works with ASP.NET (and supports a wide variety of browsers and mobile devices as clients), XML support, enhanced database access, and a whole lot more.

And parts of the .NET Framework will be available for a wide range of devices in the .NET Compact Framework—so learning the .NET Framework for PCs and servers will pay off when you need to program devices.

And standardized...

Finally, a major part of the .NET runtime, the common language infrastructure (CLI), has been standardized, along with the C# language and IL format, by the European Computer Manufacturers Association (ECMA)—the group that standardized JavaScript and JScript (http://www.ecma-international.org/publications/standards/ECMA-262.HTM)—and by the ISO (International Organization for Standardization). This is opening the way for other organizations to do compatible .NET implementations on other platforms. See the ECMA and ISO/IEC C# and Common Language Infrastructure Standards for more information.

Also, it's worth noting that Ximian, an open-source software company, is sponsoring an open-source project called Mono (http://www.go-mono.com/), which is working on an open-source version of the .NET Framework. You might find Dare Obasanjo's interview with Miguel de Icaza, leader of the Mono project, interesting.

Program for the .NET Framework with an incredible tool: Visual Studio .NET

Not only is the .NET Framework wonderful, but when you use Visual Studio .NET to develop your application, you get an extremely powerful development environment that puts everything you need at your fingertips. Documentation is integrated right into the Visual Studio .NET integrated development environment (IDE), including Dynamic Help, which watches what you type and click and guesses what Help topics are relevant to what you're doing. When it's right (and it often is), the help you need is just a click away.

Microsoft IntelliSense® helps you type statements, variable names, and member names correctly, and even shows you the names of parameters of the methods you're calling. (It does this for the classes you write as well as those in the library.) This makes editing source code much easier, faster, and less error-prone.

And there are a lot of other great features, too—Visual Studio .NET is really a very pleasant way to program—and productive, too!

Why Learn the .NET Framework?

You might be wondering, if you already program for another platform such as Windows or Linux or Java, why you'd want to bother learning a new platform: the .NET Framework.

Dr. GUI sees it this way: Since the .NET Framework is a platform that allows programmers to be very productive—it's probably the most productive of the platforms mentioned—you'd be foolish not to learn it. It's not the best platform for EVERY project (no platform is), but the good doctor thinks you'll find it the best platform for MANY of your projects. (And because it interoperates with other platforms well, you may want to do the parts of your project that make sense for the .NET Framework in the .NET Framework and interoperate, whether with native code, COM objects, or other computer systems, for the rest of your projects.

And for some kinds of applications, the .NET Framework is the obvious way to go. Web applications are really easy and powerful with ASP.NET. And XML Web services are really easy to write with the .NET Framework, too.

If you're already committed to learning the .NET Framework because you need it for a project, read on—Dr. GUI will help you. But if you're not sure, keep reading as well. For a relatively small investment of time, Dr. GUI will help you gain a good understanding of a platform you're likely to want to use. (And even if you don't, learning it will help you with your other programming, just as learning a foreign language helps you understand your native tongue better.)

DDr. GUI's Prescription: Exercise with .NET for Just an Hour a Week...

...and build strong programming muscles

Because .NET is relatively new, what Dr. GUI suggests you do to get ahead of the curve is this: Find just an hour a week to learn about .NET.

These tutorial articles will be published twice a month—and they'll have exercises you can do to actually learn what you're reading about. So, assuming it takes an hour to read the article (subsequent articles will be shorter, Dr. GUI promises, and will probably take less time than that) and an hour or two to do the exercises, you should be able to learn about some great new technology with relatively little effort—an average of about an hour a week.

If you'll devote an hour a week, you'll gain solid knowledge of the .NET Framework. You'll understand how it works and will be comfortable programming for the .NET platform.

Do it with a friend (or two, or more ...)

Just as having a workout partner can help you with your technique, not to mention your commitment, having a friend or coworker do Dr. GUI .NET with you each time will help you learn better—and have more fun. Or, better yet, get a group of people together. Perhaps you'll want to have a discussion group. Or maybe you'll just send e-mail to each other when you're done with each set of exercises—or when you're stumped and have questions.

Hang out in the Dr. GUI .NET forum on GotDotNet

There's also a new forum on GotDotNet associated with this column at http://gotdotnet.com/community/messageboard/MessageBoard.aspx?id=46.

The good doctor can't answer your .NET Framework programming questions on the forum, but he will answer your questions about these columns.

Get started for free

And don't forget that you can get the .NET Framework SDK from MSDN, including the compilers you'll need and even a debugger, for free. It's a great way to get your feet wet. Dr. GUI's pretty sure that you'll soon want to get a copy of Visual Studio .NET, though, for the cool IDE, Help system, and debugger, not to mention the IntelliSense features.

What Will We Be Discussing?

Given that the vastness of the .NET Framework, you might be wondering what we will discuss, and when?

We'll start this column with the very basics. You've already read about what problems the .NET Framework is designed to solve. Next, we'll talk about various aspects of the .NET runtime, including the obligatory "Hello World" program, and an introduction to metadata and the intermediate language (IL)—the machine language of .NET—will be provided.

Next time, we'll begin talking about the basics of the .NET Framework, including the mother of all classes, System.Object. We'll also talk about garbage collection and a bit about interfaces.

After that, we'll spend several articles working with the basics of the .NET Framework and the runtime: data types, exceptions, file and network I/O, serialization, threading and timers, and debugging.

Then we'll work on something near and dear to Windows programmers: the graphical user interface classes. (This probably won't be as interesting for ASP.NET programmers.)

There are a lot of great features in the .NET Framework for database access, XML, and Web applications, but the good doctor is currently planning on letting others address those issues.

Each column will have a sample program, explanation of the sample, and exercises you can try. The samples, all written in C# and Visual Basic .NET (including ASP.NET versions with Visual Basic .NET), will focus on illuminating larger concepts so you have a better understanding of the design philosophy behind .NET.

Why C# and Visual Basic .NET?

Why, if .NET supports 20 or so languages, will all of Dr. GUI's columns about .NET use only C# and Visual Basic .NET? Well, at first the beta versions of the Dr. GUI .NET columns were using only C#. At the time the good doctor started the column, C# was the obvious choice. Here's why: Much of the .NET Framework is written in C#, so most of the early examples were also in C#. It just seemed like the obvious way to go at the time. (Don't forget that Dr. GUI is a C++ kinda guy, too.)

But nowadays, Visual Basic .NET is almost every bit as powerful as C# (there are some features in each that aren't in the other), so it's an equally good choice for .NET programming—and today it's obvious that Dr. GUI .NET should use both languages. Thus, the good doctor (with the help of Duncan Mackenzie, author of Coding4Fun—thanks, Duncan!) has both C# and Visual Basic .NET samples in the columns.

But wait ... there's more! In order to make these columns relevant to you ASP and ASP.NET programmers, Dr. GUI is also including samples in ASP.NET, using Visual Basic .NET. You won't learn to be a great ASP.NET programmer from these columns (there are much better places, such as https://asp.net/, to work on that), but you will learn to make full and intelligent use of the full power of the .NET Framework in your ASP.NET programs, making you a better programmer since you'll understand your tools better. And if you're not currently an ASP.NET programmer, you'll get a taste of how easy and powerful ASP.NET is.

While you can program in .NET in many languages, C# and Visual Basic .NET were specifically designed to work well with .NET and to support component-based programming. And they're both great languages to program in—especially when you use Visual Studio. They're easy to use, but with none of the annoying problems of Brand J. For instance, you can actually write a swap function in C# and Visual Basic .NET, as we'll show later in this column. (Not being able to do so in Brand J is one of Dr. GUI's pet peeves about that language.)

Dr. GUI thinks that C# and Visual Basic .NET will probably be the most popular languages for .NET Framework programming. Which should you use? Whichever you prefer. Besides, by using C# and Visual Basic .NET, you'll have an opportunity to start to learn both languages as well as .NET. If you choose to use another language, seeing examples in these languages won't hurt; what you learn about the .NET Framework and runtime will apply to any language you use.

If you prefer to use some other language, it's a relatively simple process to translate the code into your language of choice. But Dr. GUI, being just one guy, doesn't have the time to do this. If one of you wants to take it on, you can leave your translations in the newsgroup that's been set up to discuss these columns. (More on this later.)

I Use Visual Basic Now. Why Use Visual Basic .NET Rather Than C#?

Dr. GUI has heard from a number of Microsoft Visual Basic programmers who were considering switching to a language other than Visual Basic .NET, such as C#, when they move to .NET. The good doctor would like to ask them to reconsider before doing so.

The reasons he's heard include things like, "Since Visual Basic is changing a lot, I may as well learn a new, more powerful language."

If it were true that other languages are more powerful than Visual Basic .NET, this might make sense. But the relationship of Visual Basic .NET to the .NET Framework is not like the relationship of Visual Basic to Windows. In general, .NET languages are on a level playing field, and are more or less equally powerful. The differences are small.

Recall that Visual Basic for Windows requires a heavyweight runtime library to interface with Windows. As a result, Visual Basic programming is in many ways very much unlike Windows programming in C or C++. That's often a good thing, since Windows is pretty complicated—Visual Basic programming is much easier. The problem is that Visual Basic for Windows is more or less limited to doing what the designers of the runtime library had in mind when they designed the runtime. If you want to do things they didn't plan for, it can be very difficult—sometimes almost impossible. (With computers, nothing is impossible.)

Visual Basic .NET, on the other hand, talks directly to the .NET Framework, just like every other .NET language. (There is a small Visual Basic .NET runtime to provide some Visual Basic-specific functions that aren't in the .NET Framework. But it's nothing like the old runtime.)

In other words, for the first time, Visual Basic .NET gives you the full power of the underlying platform. There's almost nothing you can do in C# that you can't do in Visual Basic .NET. Now there are some language feature differences—each language has a small set of features the other doesn't have. But these differences are minimal.

For instance, since Visual Basic .NET supports late binding directly, it's much easier to do in Visual Basic .NET than in other languages. And Visual Basic .NET automatically wires events to correctly named event-handling methods, saving you some code that's necessary in other languages.

On the other hand, C# allows you to write "unsafe" managed code (more accurately, code that can't be verified as type-safe) that manipulates pointers in a manner similar to C and C++. And C++ with the Managed Extensions to C++ allows you to do things like mix managed and unmanaged code. But these are things you'd want to do for very specific performance reasons, not in everyday programming.

But you don't have to pick one language for everything: With the excellent mixed-language capabilities of the .NET Framework, you can write just the parts of your program that need C++ or C# in those languages, and do the rest in the language of your choice.

The key here is this: If you're already a Visual Basic programmer, you don't have to learn a whole new language just to take advantage of the .NET Framework. Instead, you can learn the differences between Visual Basic 6.0 and Visual Basic .NET and concentrate on learning the .NET Framework well, including inheritance and exceptions. You'll be able to do everything a C# programmer can do. And, if you decide to learn C# later on, almost everything you learned using Visual Basic .NET will transfer directly to C#. (Dr. GUI suspects that programmers who know both Visual Basic .NET and C# will command higher salaries than those who know only one or the other, so, just as in real life, being bilingual is good.)

So, what Dr. GUI recommends is this:

  • If you program mostly in Visual Basic now, learn Visual Basic .NET and the .NET Framework. If you want, you can learn C# later on at your leisure. Almost everything you learn in Visual Basic .NET will apply to C#.
  • If you program mostly in C, C++, or Brand J, learn C# and the .NET Framework. (You can also stick to C++ or J#, if you prefer.) If you want to boost your salary, learn other languages such as Visual Basic .NET later on.
  • If you need to interoperate with a lot of unmanaged C/C++ code, or if you need every ounce of performance, use the Managed Extensions for C++ for the code that needs to really be fast, and C# for the rest.
  • If you program mostly in Microsoft Jscript® or JavaScript, learn Jscript .NET and the .NET Framework, branching into other languages as you please.
  • If you're managing a project, pick the language that will cause the least grief for your team. And feel free to use another language for parts of the problem that require it.

In other words, it really doesn't matter which language you use. You'll be able to do anything in the .NET Framework in any language. Varying language features will, of course, make some tasks easier in some languages than in others. For instance, as mentioned before, Visual Basic .NET offers automatic late binding—you need to write a couple of lines of code to make late binding happen in C#. That's why it's cool to be able to mix languages so easily!

So use the language you're comfortable with for starters, and then branch out as you have the time and inclination to do so.

Or learn a new language if you prefer. It's really up to you. Just know that you don't have to learn a new language just to take advantage of the full power of the .NET Framework.

Installation Notes

Most of the installation is very straightforward—just click on the appropriate Setup program or URL, and away you go. The Setup programs are both easy to understand and effective. (Be sure to enable Microsoft® Internet Information Services [IIS] before you install if you want to use ASP.NET.)

There is one little trick, though: As you're installing the .NET Framework SDK, you might be asked whether to register environment variables so you can build from the command line. You want to do this so you can use tools from the command line. Make sure the check box is selected so that you register the environment variables and can use the command-line tools.

If you install Visual Studio .NET, you won't get a chance to select this box. Instead, start your command prompt using the Visual Studio .NET 2003 Command Prompt shortcut, which you'll find on the Start menu under Microsoft Visual Studio .NET 2003\Visual Studio .NET Tools. Using this shortcut to get a command prompt will set the path properly.

Also, make sure you don't start any programs such as Microsoft® Internet Explorer or Microsoft Outlook® during the install. Dr. GUI did this and had to repair his installation. Just wait to get your e-mail until Visual Studio .NET 2003 install is done, Okay?

Writing Programs for .NET

Visual Studio .NET is designed to make .NET programming even easier than it would be otherwise—features such as automatic statement completion and drag-and-drop form editing make using an unfamiliar API set much easier. And having Help integrated into the IDE really makes things much nicer.

We'll be using Visual Studio .NET in the future, but for this column only the good doctor would like you to do things the old-fashioned way, even if you have Visual Studio .NET: Write your source file with Notepad (or some other editor, such as Visual Studio, if you like), save it to disk, and then compile and run from the command line. (For the ASP.NET applications, copy the code to the appropriate Web application directory and use Internet Explorer to view the page.) Doing this requires only the .NET SDK, not Visual Studio .NET. Using the command-line tools will also give us an opportunity to see what files are produced and to see what's going on under the covers.

How'd You Spell That?

The conventions for using upper- and lower-case in .NET programs might be different from other languages you've used. However, the rules for .NET are simple: For all identifiers other than parameter names and private field names, capitalize the first letter of every word, including the first. This is called "Pascal casing," after the convention common among Pascal programmers.

For parameter names and private field names, capitalize the first letter of every word except the first. (Microsoft recommends that all fields be private; however, they may be exposed with a protected or public property.) This is called "camel casing." Dr. GUI isn't quite sure why.

You really need to know these rules, because the .NET Framework names adhere to them and some languages, such as C#, are case-sensitive.

So, the name of the main output function is System.Console.WriteLine, with exactly that capitalization. The name of the format string parameter for System.Console.WriteLine might be formatString, not FormatString. But the name of the length property of a string might be StrLen, not strLen.

For Dr. GUI, the hardest one to remember is to use Main, not main.

Hello World .NET in C# and Visual Basic .NET

So, without further ado, here is the simplest possible "Hello World" in C# for .NET:

C#

// Compile with: csc hellocs.cs
class MyApp {
   public static void Main() {
      System.Console.WriteLine("Hello, world! (from C#)");
   }
}

…and here is the code in Visual Basic .NET:

Visual Basic .NET

' Compile with: vbc hellovb.vb
Class MyApp
   Public Shared Sub Main()
      System.Console.WriteLine("Hello, world! " + _
         "(from Visual Basic .NET)")
   End Sub
End Class

Running the programs

To run these programs, just create (or get from the newsgroup) the text file with the code, and then compile using the command line shown in the code. (Run sdkvars.bat in the Framework SDK's \bin directory [C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin on Dr. GUI's machine] if needed to set the path so the compiler will work.)

Then type the name of the program to run it. For example once you've created the files, you could type one of the following:

   rem C#
   csc hellocs.cs
   hellocs

   rem VB .NET
   vbc hellovb.vb
   hellovb

Everything's in a class

The first thing you're likely to notice is that the Main function is a member of a class.

In .NET, all methods must be members of a class or struct. (We'll talk more about structs next time.) That's because the basic unit of organization in .NET is a type (a type is, among other things, a class or struct). The Managed C++ extensions for Visual C++ .NET allow you to write variables and functions ostensibly outside of a class, but even those are in a class: an implied global class.

Look Ma! No headers!

Not only is everything in a class, but the class declarations are complete. There are no header files, IDL files, or any other files besides the source file. Everything you need to describe the class is with the class.

So what happens if you use another class that's not in your source file? How does the compiler know what's in that class?

The answer is that the compiler reads the metadata of the assembly that contains the class you're using. The program just shown uses System.Object implicitly (because all classes are derived from System.Object). The compiler automatically goes to the mscorlib.dll assembly to get the metadata for that assembly so it can get the type information it needs for System.Object. If you use classes from different assemblies, you use the /r option on the compiler command line to specify the assembly, such as:

   rem C#
   csc /r:foo.dll hellocs.cs

   rem VB .NET
   vbc /r:foo.dll hellovb.vb

By the way, a module (*NOT* the same as the Module in Visual Basic .NET!) is an executable file—either an application or a library. Its extension is usually .exe or .dll. An assembly is a set of one or more modules. One file in the assembly has the assembly's manifest, or list of files in that assembly. An assembly is the smallest unit of executable code that can be deployed and versioned. (You'll note when we look at the manifest for an assembly later on that only assemblies have version numbers.)

Main is special

You'll next likely notice the modifiers on Main: public and static (Shared in Visual Basic .NET). The default access control for members in these languages is private; thus we need to declare Main public so it can be called by the runtime.

We declare Main as static (Shared in Visual Basic .NET), meaning that it's a class method rather than an instance method. That means the runtime can call it without being concerned about creating a MyApp object and passing a this reference (Me in Visual Basic .NET) to that object to Main. (Note that if we were using a Module in Visual Basic .NET, the methods would default to Public and Shared.)

Note that you can call the class anything; I happened to call it MyApp here. This version of Main takes no parameters and returns nothing, indicated by a return type of void. In Visual Basic .NET, Main is a Sub rather than a function with void return value.

It's possible to write Main to take an array of Strings that hold the command-line parameter and/or to return an integer success code.

Finally, we're calling the WriteLine method to write the string. I've chosen to use the fully qualified name for the function System.Console.WriteLine. WriteLine is a static method (like Main) of the Console class in the System namespace.

Saving some typing

It' a pain to constantly type fully qualified class names, so C# and Visual Basic .NET allow you to specify namespaces to be used with the using (or Imports) statement. For instance:

C#

// Compile with: csc hellocs2.cs
using System;
class MyApp {
   public static void Main() {
      Console.WriteLine("Hello, world! (2) (from C#)");
   }
}

Visual Basic .NET

' Compile with: vbc hellovb2.vb
Imports System
Module MyApp ' VB-only change
    Sub Main()
        Console.WriteLine("Hello world! (2) (from VB .NET)")
    End Sub
End Module

Because the compiler is searching the System namespace as well as the local namespace, we didn't have to specify System in the call to Console.WriteLine. This isn't a big win here, but it's very handy when you have many object references and method calls, as in the programs to follow.

Note that the namespace (System) and the assembly in which you'll find the class Console are two entirely separate things. A given assembly can contain classes from more than one namespace; by the same token, the classes in a given namespace can be spread across more than one assembly. There is no relationship between the namespace a class is logically a part of and the assembly where the binary code for the class can be found. You tell the compiler where to find the binary code for the class using the /r option. You tell the compiler what namespaces to use with the using and Imports statements.

For Visual Basic only: Modules vs. classes

We made one other change in the Visual Basic .NET version: Rather than MyApp being a regular class, we've made it a special type of class called a Module. A Module is what a static class would be in C# if C# had such a thing. Mainly, all of the methods are shared (static in C#) and public; therefore, we don't need to declare Main as Shared or Public. But note that you can't create an instance of a Module as you can a class.

Wait! Don't leave yet!

In some situations—for instance, if you run Hello program from the File Explorer—the command window might disappear before you can see the output. To prevent this, read from the keyboard (which will cause the program to pause until you press Enter) by calling Console's ReadLine method. (We'll always make this the last statement in Main for console applications.)

So, our program finally looks like this (we've switched back to a class in Visual Basic .NET):

C#

// Compile with: csc hellocspause.cs
using System;
class MyApp {
   public static void Main() {
      Console.WriteLine("Hello, world! (pause) (from C#)");
      Console.ReadLine();   // wait until Enter; last line
   }
}

Visual Basic .NET

' Compile with: vbc hellovbpause.vb
Imports System
Public Class MyApp
    Public Shared Sub Main()
        Console.WriteLine("Hello world! (pause) (from VB .NET)")
        Console.ReadLine() 'Wait until Enter; last line
    End Sub
End Class

Hello World in ASP.NET (in Visual Basic .NET and C#)

About Web applications

When you write an ASP.NET program, you're writing programs that create and interact with Web pages—so your program isn't as simple as just writing a few characters to the console and waiting for input. Instead, your program uses a Web page to communicate with the user and needs to respond to things the user does to the page. You have to take this extra complication into account, even if you're doing something simple like "Hello, World!"

Originally, the Web was intended for distribution of documents so Web servers just took a URL from the browser and delivered the disk file (formatted in HTML) that corresponds with that URL. But merely delivering static content didn't allow for very sophisticated applications, so Web servers quickly evolved to support forms and various sorts of dynamic content. One common technique for doing this is to send the data in the form to a stand-alone program that parses the fields of the form, decides what to do, and builds a response to be displayed in the user's browser.

ASP

One of the more popular ways of hooking up a Web page to code that runs on the server has been the Microsoft Active Server Pages, more commonly known as ASP. In ASP, you build interpreted script (usually Microsoft Visual Basic Scripting Edition (VBScript), sometimes JScript or one of a few other languages) into the Web pages themselves. When the server processes this page, it interprets and executes the script as it reads through the page to determine what response to send to the browser. This integration of HTML and a programming language made writing ASP pages relatively easy, and therefore popular. But it means that your programming logic (script) is tied up in the same files that contain your formatting (the HTML).

Where's your script?

Note that it's possible to do both client-side scripting (where the script is sent as part of the HTML page to the browser, which executes the code, typically in JScript/JavaScript) and server-side scripting (as just described, in ASP pages, executed on the server, and typically VBScript).

We're only dealing with server-side script for the Dr. GUI .NET series (at least for the most part...)—there are hundreds (if not thousands) of other places to learn how to do client-side scripting.

The request/response model

Recall that in Web pages you send some sort of HTTP request (for example, a URL and the data in a form) to the server and it sends back some sort of a response (a Web page) to you. Your browser then typically displays that response. When you click various Web page elements, such as buttons or links, one of two things can happen: If the Web page has client-side script code (downloaded with the Web page, and typically in JScript/JavaScript), an event handler may handle the event without even talking to the server. Or, depending on the HTML code for the Web page element (such as a button), your browser might send an HTTP request to the server. This is typically what happens when you click the Submit button on a form.

This programming model can be fairly difficult to use because you have to know a lot about HTTP requests and responses. And the model is radically different than the much simpler event-driven forms and controls model that most Windows applications, especially Visual Basic applications, use.

The programming model for "classic" ASP is based on the HTTP request/response model—it's basically a thin wrapper around requests and responses, with plumbing included to allow you to get at the fields of the request, write script to manipulate and query data, and write output into the response. This is helpful, but we can do better.

If you're used to this model, don't despair: You can still run ASP applications side-by-side with ASP.NET applications. You can even, if you know what you're doing with application state and other issues, convert ASP applications page-by-page to ASP.NET.

The ASP.NET forms-based model

The programming model in ASP.NET adds radically different elements: forms and controls. The programming model embodied by ASP.NET Web Forms is fairly similar to that of a Windows application (and especially similar to a Visual Basic form), although the mechanisms underneath the programming models are very different.

Conceptually, a pure Web Forms application consists of a set of forms that contain controls and HTML. The controls have properties and methods and generate events. These events are usually handled on the server, although it's certainly possible to write client-side script to handle certain events on the client. (But that's beyond the scope of this column.)

In other words, the Web Forms programming model is virtually identical to the Visual Basic programming model. So if you know Visual Basic, you'll love Web Forms. This is a much simpler model than the ASP model.

So, even the simplest applications we do here will be thoroughly modern Web Forms applications. Note that, interestingly enough, the language used to describe the layout of the Web Forms is very much like standard HTML (with mainly a few extra attributes and control names).

And now our code ...

Without further ado, let's look at our first Web Forms application—this time using Visual Basic .NET with the code embedded, ASP-style, right in the helloinlinevb.aspx file, and then with the C# equivalent:

ASP.NET with Visual Basic .NET

<script runat="server" language="vb">
   Public Sub doClick(sender as object, e as EventArgs)
      TheLabel.Text = "Hello, world! (from ASP.NET in VB .NET, " + _
         "code inline)"
   End Sub
</script>
<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form runat="server">
         <asp:button runat="server" text="Say Hello" 
            onclick="doClick" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</html>

ASP.NET with C#

<script runat="server" language="C#">
   void doClick(object sender, EventArgs e) {
      TheLabel.Text = "Hello, world! (from ASP.NET in C#, " +
         "code inline)";
   }
</script>
<html>
   <head><title>In-line ASPX file in C#</title></head>
   <body>
      C# ASP.NET application with inline code<P><P>
      <form runat="server">
         <asp:button runat="server" text="Say Hello" 
            onclick="doClick" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</html>

Not much difference between languages

First, notice that the C# page is very similar to the Visual Basic .NET code. Aside from the code itself, the only changes are to change the language attribute on the <SCRIPT> tag to C# and to change the titles and text to say "C#" instead of "Visual Basic .NET." We could substitute any ASP.NET-compatible language, such as JScript .NET, just as easily.

Where's Main?

You'll also notice that there's no Main method. Your code is run by ASP.NET, so there's no need for Main. Instead, your event handlers will be called when appropriate. This difference is very similar to moving from DOS to Windows event-driven programming, especially as is done in Visual Basic.

So what's the code do?

Some things to note: First, we have a small Visual Basic .NET subroutine (a method that returns void in C#) that sets the label called "TheLabel" in the HTML below to our message when the subroutine is called. This is enclosed in a <SCRIPT> tag that specifies to run this script at the server and that the code is in Visual Basic (or C#). Note that we're ignoring the parameters we're passed—they serve to tell us about the event that's occurred, but for now the fact that event has occurred is all we care about.

Now the HTML for the Web page layout

Next, we have the HTML code for the page itself. If you're familiar at all with HTML, this part will look very familiar to you. Except for three things: the form, button, and label are marked with the runat="server" attribute, the button is declared as an "asp:button" rather than just a regular HTML input button, and there's this odd label thing called "asp:label". Oh, and one other thing: The form doesn't have any stuff about posting or action.

Running our first ASP.NET applications

If you use Visual Studio .NET to build your Web Forms application, it's very easy to build and it runs correctly automatically when you click the Run button. It's really slick. We'll talk more about it later. And if you use Web Matrix, it's just as easy—and Web Matrix includes its own mini-Web server, so you don't even have to install IIS if you don't want to.

But for now, let's do everything with Notepad and handle all the files ourselves.

Running ASP.NET applications is a little more complicated than running a console application. But once you get things set up, it's really pretty easy.

First, you have to install the IIS Web server. You should have done this before you installed the .NET Framework or Visual Studio .NET. If you have problems with this, you should be able to install IIS and reinstall just the server components using the Setup program. You install Windows components such as IIS in Control Panel (on the Start menu, click Control Panel, and then double-click the Add/Remove Programs icon. Then click Add/Remove Windows Components on the left, and select Internet Information Service (IIS)).

Next, you'll need to enable IIS as a Web server. To do this, on the Start menu, click Control Panel, double-click the Administrative Tools icon, and then click Internet Information Services or Internet Information Services (IIS) Manager. (Dr. GUI is using Windows XP Professional and Microsoft® Windows® Server 2003; if you're using a different operating system, things might be called something slightly different.)

From the Internet Information Services console, click the little plus sign next to your computer's icon. Then, click the little plus sign next to the Web Sites folder. You should see an entry for the Default Web site, as shown here.

Figure 1. Internet Information Services console with default Web site selected

If the Default Web site indicates that it's stopped, you'll need to start the service. To do this, right-click Default Web site and click Start.

Note If you don't understand security issues associated with IIS, you may not want to do this if your machine is connected directly to the Internet without a firewall.

Note   You can also use the Web server built into Web Matrix for testing your applicationsyou don't even need to install IIS. To do this, follow the directions in Web Matrix.

Now the Web server is up and running. (You can stop it when you're done by right-clicking Default Web site again and clicking Stop.) All we have to do is copy the files to the right directory and IIS will do its magic.

Installing the application

To open the correct IIS folder, right-click Default Web site and then click Open. This will open the folder that IIS is using for that Web site.

Dr. GUI recommends making a subfolder (or two) for your project. Dr. GUI calls his subfolder tree "DrGUIdotNet\0" for the Web pages associated with Dr. GUI .NET #0.

Once you've made a subfolder, copy the ASPX page(s) into it.

Figure 2. The Web application files copied to the correct folder

Running your application

Finally, go to your Web browser and browse the file on your local machine. On Dr. GUI's machine, the URLs are https://localhost/DrGUIdotNet/0/helloinlinevb.aspx and https://localhost/DrGUIdotNet/0/helloinlinecs.aspx. The "localhost" domain refers to your machine. And if you named your subdirectories and .aspx file as the good doctor did, you'll find that the URL above will work for you, too.

Note that you must use http: as your protocol—if you try to open the .aspx file from the file system using Internet Explorer, you'll end up bypassing IIS, meaning that your code won't be run.

Once you've got the Web page up correctly, just click the Say Hello button and ASP.NET will greet you.

Figure 3. Hello World! application in Visual Basic .NET with inline codeafter clicking button

But notice that you didn't compile anything! ASP.NET did that for you. If you want to change the code, just modify it (Dr. GUI just leaves Notepad up and running and does a File.Save to write to disk) and reload the Web page (click the Back button if you want to get the original state). ASP.NET takes care of all the updating for you. Cool, huh?

So what's the HTML look like in the browser?

By the way, when you run the application, you can look at the HTML that appears in the browser. You'll note that it's very different from the .aspx file—those differences are the processing that ASP.NET does for you. For instance, the Visual Basic .NET application generates the following HTML before you click the button (the C# version is pretty much identical except for replacing "Visual Basic .NET" with "C#" in two places below):

HTML generated by ASP.NET application before button click

<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form name="_ctl0" method="post" action="helloinlinevb.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value=
"dDwxMDA3MzE2MzEyOzs+O3sv0P01UevZXFJOLqBbw+4DdQ4=" />

         <input type="submit" name="_ctl1" value="Say Hello" />
         <p>
         <span id="TheLabel"></span>
      </form>

   </body>
</html>

The major differences between the HTML sent to the client and the original .aspx file are in the form. First, the form itself has a few special attributes so it can communicate with ASP.NET. Next, there's an added hidden INPUT tag that's used to store data about the state of the page being viewed. Finally, all the ASP.NET controls (the ones that began with "asp." in the .aspx file) have been rendered as proper HTML—in this case, an input Submit button and, for the label, a SPAN of text.

The fact that ASP.NET writes the HTML for ASP.NET controls for you is extremely powerful: It means that if you use ASP.NET controls, you don't have to worry about writing different HTML for different browsers. Instead, ASP.NET detects what browser the user is using and generates the appropriate HTML for that browser. All you do is use the high-level controls and let ASP.NET deal with the details. (This does not, however, get you out of testing your application against all the browsers you intend to support.)

What happens when you click the button

When you click the button to say "Hello," an HTTP request is sent to the server and ASP.NET determines from this request that the script code for the button click should be run. After running the code, ASP.NET generates the page anew using the updated values of the controls and sends it to the browser:

HTML generated by ASP.NET application after button click

<html>
   <head><title>In-line ASPX file in VB .NET</title></head>
   <body>
      VB .NET ASP.NET application with inline code<P><P>
      <form name="_ctl0" method="post" action="helloinlinevb.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwxMDA3Mz
E2MzEyO3Q8O2w8aTwxPjs+O2w8dDw7bDxpPDM+Oz47bDx0PHA8cDxsPFR
leHQ7PjtsPEhlbGxvLCB3b3JsZCEgKGZyb20gQVNQLk5FVCBpbiBWQiAuTkVULCBjb2RlIGlub
GluZSk7Pj47Pjs7Pjs+Pjs+Pjs+BQyLRwj8cd6YqwFn4gpQYk2NhTY=" />

         <input type="submit" name="_ctl1" value="Say Hello" />
         <p>
         <span id="TheLabel">Hello, world! (from ASP.NET in VB
 .NET, code inline)</span>
      </form>
   </body>
</html>

In this case, the HTML is the same as before, with two exceptions: First, the value attribute of the hidden INPUT item is different; second, the new value of the string to which TheLabel was set in your code appears in the SPAN tag that was generated by the label control.

You might be wondering if ASP.NET is interpreting your code. The answer is no—instead, ASP.NET cuts the code out and compiles it, storing the resulting assembly in a private cache. It recompiles it only if you change the source code. You usually don't want or need to look at the resulting assembly, but later on Dr. GUI will show you how to find it (just this once).

Code behind

In classic ASP, you intermixed your VBScript code right into your HTML pages (similar to what we just did), and you would often write HTML code directly into the response. The ASP.NET equivalent of this method is shown above.

But ASP.NET also supports separating out the code file from the HTML-like .aspx file. This is called "code behind." The advantage of this is that it's considerably easier to work both on the HTML and the code if they're cleanly separated—especially if different people work on the HTML layout than the code logic, as if often the case.

We'll be using the code-behind feature for all the future Dr. GUI .NET ASP.NET examples, because it just plain looks nicer.

For our "Hello" application, we'll have two files: the .aspx file that contains the HTML and reference to the code file, and the Visual Basic .NET (.vb) and C# (.cs) files for the actual code. For our Visual Basic .NET version, the hellocodebehindvb.aspx file looks like this:

ASP.NET with Visual Basic .NET code behind

<%@ Page Language="vb" Src="hellocodebehindvb.vb" 
         Inherits="HelloWebFormVb"%>
<HTML>
   <HEAD>
      <title>Web Form</title>
   </HEAD>
   <body>
   VB .NET ASP.NET application with "Code Behind"<P><P>
      <form runat="server" ID="Form1">
         <asp:button runat="server" text="Say Hello" 
            ID="Button1" />
         <p>
         <asp:label runat="server" text="" id="TheLabel" />
      </form>
   </body>
</HTML>

The differences from the code inline version are:

  • The SCRIPT section of the inline version is replaced by a special tag that specifies the language, source file name, and class name in that source file of the class our page will be using.
  • The code itself is in a separate file.
  • The button doesn't designate a method to be called when it's clicked—ASP.NET links up the button click to the method automatically.
  • All of the ASP.NET controls have IDs so they can be accessed from the code.

The C# version of the .aspx file is the same as the preceding file, except for the language, source file name, and file name—and text in the title and on the page. It's in the listing file source code that accompanies this article.

The Visual Basic .NET code for the code-behind class is quite simple:

Visual Basic .NET "code-behind" code for above

Public Class HelloWebFormVb
    Inherits System.Web.UI.Page
    Protected WithEvents Button1 As System.Web.UI.WebControls.Button
    Protected TheLabel As System.Web.UI.WebControls.Label

    Private Sub Button1_Click(ByVal sender As Object, 
      ByVal e As System.EventArgs) Handles Button1.Click
      TheLabel.Text = _
        "Hello, world! (from an ASP.NET/VB .NET WebForm with code behind)"
    End Sub
End Class

Note that the class name is the same as specified by the Inherits attribute at the top of the .aspx file. Implied by this is that the page class for your application inherits from this class—in this case, HelloWebFormVb (or HelloWebFormCs if you're using C#). If you're not familiar with inheritance, don't worry about it too much for now. We'll be discussing it in a future Dr. GUI .NET column. For the time being, just think of it as when you inherit from something, you get to use all of the functionality of the thing you inherit from—pretty handy!

You'll note that our class inherits from System.Web.UI.Page, which has a great deal of functionality we can use.

Next, we declare a variable that correspond to the button and the label in the HTML. Note that the names are the same as the IDs in the .aspx file. Also note that the button is declared with WithEvents, because we'll be handling its click event.

After that, we declare the click handler. (Note the Handles clause.) The rest of the code is very similar to the inline script code.

The following is the C# version:

C# "code behind" code

public class HelloWebFormCs : System.Web.UI.Page
{
   protected System.Web.UI.WebControls.Button Button1;
   protected System.Web.UI.WebControls.Label TheLabel;

   override protected void OnInit(System.EventArgs e)
   {
      this.Button1.Click += 
         new System.EventHandler(this.Button1_Click);
      base.OnInit(e);
   }

   private void Button1_Click(object sender, System.EventArgs e)
   {
      TheLabel.Text = 
      "Hello, world! (from an ASP.NET/C# WebForm with code behind)";
   }
}

It's very similar to the Visual Basic .NET version in terms of inheritance, but since C# doesn't support automatically connecting up events with handler methods, we have to explicitly do this. In order to do this, we override the OnInit method and connect the handler, and then call the base class's OnInit method. We'll talk about how the handler connection works when we discuss delegates and events in a later column. For now, just know that the OnInit method we've declared is automatically called when the page is initialized and that the statement inside hooks up the click event fired by the button to the Button1_Click method.

We'll also talk about overriding and calling base class methods when we talk about inheritance in a future column. For now, just know that that funky statement hooks up the click event of the button to be handled by the Button1_Click method.

Using Visual Studio .NET for Web Forms applications

Using Visual Studio .NET for creating Web Forms applications is incredibly easy. Just create a new project of the type "ASP.NET Web Application" in the language of your choice (either C# or Visual Basic .NET), drag a button and a label onto your Web page, and double-click the button so you can add the code to set the label. You can do it all in about a minute flat, including running the program to check the results. It's amazing, and well worth paying for Visual Studio .NET!

See? You Can Swap in C# and Visual Basic .NET!

As the good doctor just mentioned, in C# and Visual Basic .NET, unlike some other languages, such as Brand J, you can write a function that swaps two variables.

Here are programs that swap the contents of two integer variables:

C#

// Compile with: csc swapcs.cs
using System;
class SwapInts {
   public static void Main() {
      int i = 1, j = 2;
      Console.WriteLine("C#: i is {0}, j is {1}", i, j);
      Swap(ref i, ref j);
      Console.WriteLine("i is {0}, j is {1}", i, j);
      Console.WriteLine(
         "i is still {1:####}, and j still is {0:####}",
         j, i
      );
      Console.ReadLine();
   }

   static void Swap(ref int a, ref int b) {
      int t = a;
      a = b;
      b = t;
   }
}

Visual Basic .NET

' Compile with: vbc swapvb.vb
Imports System
Public Class SwapInts ' used class, not module, here...
    Public Shared Sub Main() ' ...so had to declare public, shared
        Dim i As Integer = 1, j As Integer = 2
        Console.WriteLine("VB .NET: i is {0}, j is {1}", i, j)
        Swap(i, j) ' don't have to use "ref" to call!
        Console.WriteLine("i is {0}, j is {1}", i, j)
        Console.WriteLine( _
            "i is still {1:####}, and j still is {0:####}", _
            j, i)
        Console.ReadLine()
    End Sub

    Private Shared Sub Swap(ByRef a As Integer, ByRef b As Integer)
        Dim t As Integer = a
        a = b
        b = t
    End Sub
End Class

There are a few things to note here. First, the good doctor has chosen to use the C# type int and the Visual Basic .NET type Integer rather than the .NET Framework type System.Int32 (the full name of Int32). Because int in C# and Integer in Visual Basic .NET are simply aliases for System.Int32, there is no difference at all, and you could easily use Int32 or System.Int32 in either the C# or Visual Basic .NET programs.

Some programmers prefer to use the Framework types (such as Int32), but since the samples and documentation use the built-in types instead, Dr. GUI prefers to use the built-in types.

If you want to translate either of these programs to another language, you'll have to find out which type in the new language corresponds to int/Integer/System.Int32 and use it—or use System.Int32/Int32.

Next, note the flexible formatting provided by Console.WriteLine. The variables are inserted into the output string in place of the expressions in braces, {0} and {1}. The numbers 0 and 1 represent the position of parameter to be formatted. The first parameter is numbered zero, not one. (That, and the fact that array numbering also starts with zero, is why this column is Dr. GUI .NET #0, not #1.) You'll notice the good doctor has switched the variables around in the final WriteLine statement. Being able to switch the order is important when you're translating the format strings into natural languages with different grammars—you can change the format string without changing the call. In addition, it is possible to put additional formatting information in the braces, as in the last WriteLine statement. This formatting mechanism is extensible for your types as well. (We'll discuss this in a later column.)

Finally, note the most important point in the C# code: Both in the call to Swap and in the declaration of the method, the parameters passed by reference are marked with ref. This is how we tell the C# compiler that we might want to change the values of i and j when we call the method. If we don't use ref, we'd swap the copies generated when the values are passed by value. (You can try this, deleting all four instances of the word ref, and see for yourself.)

In Visual Basic .NET, we mark the parameters in the method declaration with the word Byref, but we don't have to mark each call—that's simpler, and compatible with older versions of Visual Basic, but there's no way to tell in Visual Basic .NET by looking at the call whether you're calling by reference or by value.

Swap Using ASP.NET

Of course, we can swap variables in ASP.NET programs, too. Take a look at the following .aspx program. (I'll show the Visual Basic .NET code later):

ASP.NET

<%@ Page Language="vb" Src="webswapvb.vb" Inherits="SwapWebFormVb"%>
<HTML>
   <HEAD>
      <title>Swap in VB .NET</title>
   </HEAD>
   <body>
   VB .NET ASP.NET application to swap two values<P><P>
      <form runat="server" ID="Form1">
         I:&nbsp
         <asp:textbox runat="server" text="3" ID="I" />
         J:&nbsp
         <asp:textbox runat="server" text="4" ID="J" />
         <p>
         <asp:button runat="server" text="Swap" ID="Button1" />
         <p>
      </form>
   </body>
</HTML>

This page is quite similar to the others we've seen. Note how the text (such as "I:" followed by a non-breaking space) is interspersed with the ASP.NET controls on the page. This gives you tremendous flexibility in designing your page without the hassles of worrying about where the scripting code goes. With code behind, the .aspx page contains layout and your code—including hooking up events and form elements—is all within the code file.

So let's look at the Visual Basic .NET code:

Visual Basic .NET

Public Class SwapWebFormVb
   Inherits System.Web.UI.Page
   Protected WithEvents Button1 As System.Web.UI.WebControls.Button
   Protected I As System.Web.UI.WebControls.TextBox
   Protected J As System.Web.UI.WebControls.TextBox
   Private Sub Button1_Click(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles Button1.Click
      ' VB allows properties to be passed by ref, C# doesn't
      ' However, VB generates temporarys, so it's as slow as C#
      ' ...but easier to write!
      Swap(I.Text, J.Text)
   End Sub
   Private Shared Sub Swap(ByRef a As String, ByRef b As String)
      Dim t As String = a
      a = b
      b = t
   End Sub
End Class

Again, this is pretty similar to the previous program. The main difference is that we're declaring some different controls (text boxes rather than labels) and that, in our event handler, we're reading the values out of the text boxes, swapping them, and putting them back. (Of course, it's possible to write this in fewer lines—the Swap function is here to make a point, though. And it would be useful if you were swapping other variables.)

Do note that the Swap method does not copy the strings. Instead, it swaps the references. This is much more efficient.

A note: it's technically not possible to pass a property, which is really a method call, to a method as a ByRef parameter (since you have to pass an address of a memory variable, not a function). But you notice that that's what the code above seems to be doing in Swap(I.Text, J.Text). How can this be?

Well, what's really going on here is that under the hood, Visual Basic .NET is generating code that creates a temporary for each property, passes the temporaries to the Swap method, then copies the results back to the properties. (You can prove this by looking at the generated code in ILDASM, as we'll do later in this column.)

In other words, even though the syntax is much shorter than C#'s, the actual code generated is virtually the same. Visual Basic has the advantage that it's easier; C# has the advantage that it's not hiding potentially time-consuming code from you.

C#

public class SwapWebFormCs : System.Web.UI.Page
{
   protected System.Web.UI.WebControls.TextBox I;
   protected System.Web.UI.WebControls.TextBox J;
   protected System.Web.UI.WebControls.Button Button1;
   override protected void OnInit(System.EventArgs e)
   {
      this.Button1.Click += 
         new System.EventHandler(this.Button1_Click);
      base.OnInit(e);
   }
   private void Button1_Click(object sender, System.EventArgs e)
   {   // have to move from properties to variables...
      string a = I.Text;
      string b = J.Text;
      Swap(ref a, ref b);
      I.Text = a; // and back :(
      J.Text = b;
   }
   // note that references are swapped, strings aren't moved!
   static void Swap(ref string a, ref string b) {
      string t = a;
      a = b;
      b = t;
   }
}

Again, no surprises—and note that the Swap method swaps the references to the strings, not the strings themselves. And, as you guessed, you have to write the code for the temporary variables in the call to the Swap method yourself.

Give It a Shot!

Let's do it!

Once you've got .NET installed, you can use Notepad or Visual Studio to create a file containing the last of the preceding C# "Hello World" programs. (That's the one with the Console.ReadLine call as the last line of Main. Create a new, empty subdirectory and save the file there, naming it hellocspause.cs. (CS stands for C#.) You can copy the code from this article, or get it from the newsgroup. Or, better yet, since this is short, type it yourself.

And while you're at it, do a Visual Basic .NET version and name the file hellovbpause.vb.

Next, open a command prompt and change to the directory you're using. Compile the program by typing the command "csc hellocspause.cs" ("vbc hellovbpause.vb" for Visual Basic .NET). (Remember to set the path with sdkvars.bat if you need to.)

If you look in the directory, you'll see that hellocspause.exe (and hellovbpause.exe) have been created. Execute it by typing "hellocspause" (or "hellovbpause")—your console window should display "Hello, World! (pause) (from C#)" or "Hello, World! (pause) (from Visual Basic .NET)".

What's REALLY inside that EXE?

List the contents of the directory where you stored the console applications and notice that there are only two files per program: hellocspause.cs and hellocspause.exe, and hellovbpause.vb and hellovbpause.exe. The .exe files are very small—about 3 KB or so. This is simplicity itself.

But what's inside these files? Well, that's not quite as simple. In .exe files, there's a stub loader—a small native machine language program that causes the .NET runtime to be loaded and given control so it can start executing your program. (.Dll files don't have a stub loader for the .NET runtime because the runtime will be loaded by the .exe that calls the .dll.)

But the two really important parts are the metadata, which describes your program to the common language runtime and to compilers that might reference types in your program, and the code, in IL. (You'll recall that IL is the machine language of the .NET runtime.) When the runtime is about to execute each method for the first time, it translates the IL into native code, and then executes the native code. .NET never interprets IL; it always compiles it to native code.

Using ILDASM to get to the bottom of it

How can you look at the metadata and IL? It's easy with a utility called the IL Disassembler (ILDASM). Just type "ILDASM hellovbpause.exe" (or "ILDASM hellocspause.exe") at the command prompt, assuming the .exe file is in the current directory. (We'll describe how to do this for our ASP.NET program later. For now, just do this on the console application, and then we'll talk about the ASP.NET differences.)

You'll see a window like the one shown here. (This is for the Visual Basic .NET version—the C# version is very similar.)

Figure 4. Initial ILDASM screen after you type "ILDASM hellovbpause.exe"

Initially, the tree under "hellovbpause.exe" shows two parts: a manifest, and the class MyApp. Because the module hellovbpause.exe has a manifest, we know that it is the description file for an assembly. In this case, the assembly consists of only one module file, hellovbpause.exe.

The manifest

If you double-click the manifest, you'll see a small part of the metadata—this part describes the modules (files) included in this assembly (application or component). For our third hellovb.exe, it looks something like this:

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )     // .z\V.4..
  .ver 1:0:5000:0
}
.assembly extern Microsoft.VisualBasic
{
  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )     // .?_....:
  .ver 7:0:5000:0
}
.assembly hellovbpause
{
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module hellovbpause.exe
// MVID: {B8F34B08-AB79-4FD6-9B53-3A4792204A71}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x06bf0000

This metadata just declares the assembly hellovbpause, version 0.0.0.0, as containing the module (file) hellovbpause.exe, and says that it uses the assembly mscorlib, version 1:0:5000:0;the .NET runtime main DLL. (The Visual Basic version just shown also has similar a reference to the assembly Microsoft.VisualBasic—C# programs would not have this unless they used types in the Visual Basic runtime explicitly.) The Module Version Identifier (MVID) is a globally unique identifier (GUID) that contains the ID for this version of the module hellovbpause.exe.

Module metadata

If you select the module file name ("hellovbpause.exe") and press Ctrl+M, you'll see more metadata—this time for the module, including each class and method. (Note that the good doctor has deleted much of this in an attempt at brevity.)

ScopeName : hellovbpause.exe
MVID      : {B8F34B08-AB79-4FD6-9B53-3A4792204A71}
===========================================================
Global functions
-------------------------------------------------------
Global fields
-------------------------------------------------------
Global MemberRefs
-------------------------------------------------------
TypeDef #1
-------------------------------------------------------
   TypDefName: MyApp  (02000002)
   Flags     : [Public] [AutoLayout] [Class] [AnsiClass]  (00000001)
   Extends   : 01000001 [TypeRef] System.Object
   Method #1 
   -------------------------------------------------------
      MethodName: .ctor (06000001)
      Flags     : [Public] [ReuseSlot] [SpecialName] [RTSpecialName] 
[.ctor]  (00001806)
      RVA       : 0x00002050
      ImplFlags : [IL] [Managed]  (00000000)
      CallCnvntn: [DEFAULT]
      hasThis 
      ReturnType: Void
      No arguments.

   Method #2 [ENTRYPOINT]
   -------------------------------------------------------
      MethodName: Main (06000002)
      Flags     : [Public] [Static] [ReuseSlot]  (00000016)
      RVA       : 0x00002058
      ImplFlags : [IL] [Managed]  (00000000)
      CallCnvntn: [DEFAULT]
      ReturnType: Void
      No arguments.
      CustomAttribute #1 (0c000001)
      -------------------------------------------------------
         CustomAttribute Type: 0a000004
         CustomAttributeName: System.STAThreadAttribute :: 
instance void .ctor()
         Length: 4
         Value : 01 00 00 00    >                <
         ctor args: ()

TypeRef #1 (01000001)
-------------------------------------------------------
Token:             0x01000001
ResolutionScope:   0x23000001
TypeRefName:       System.Object
   MemberRef #1
   -------------------------------------------------------
      Member: (0a000001) .ctor: 
      CallCnvntn: [DEFAULT]
      hasThis 
      ReturnType: Void
      No arguments.

TypeRef #2 (01000002)
-------------------------------------------------------
Token:             0x01000002
ResolutionScope:   0x23000001
TypeRefName:       System.Console
   MemberRef #1
   -------------------------------------------------------
      Member: (0a000002) WriteLine: 
      CallCnvntn: [DEFAULT]
      ReturnType: Void
      1 Arguments
         Argument #1:  String
   MemberRef #2
   -------------------------------------------------------
      Member: (0a000003) ReadLine: 
      CallCnvntn: [DEFAULT]
      ReturnType: String
      No arguments.

...

User Strings
-------------------------------------------------------
70000001 : (35) L"Hello world! (pause) (from VB .NET)"

You can find the definition of MyApp (TypeDef #1) and the two methods, the constructor and Main. (You didn't write the constructor, but the compiler provided it for you.) You can also see references to the objects and methods your program references, such as System.Console and its WriteLine and ReadLine methods. Again, there are a few others provided by the compiler, such as System.Object. You can look at them by building hellovbpause.exe and using ILDASM to examine it. The good doctor has also removed the assembly and assembly reference metadata, which mostly duplicates the manifest just shown. Finally, you'll see the string constant we included in our WriteLine statement.

It's not important that you understand all this now, but Dr. GUI wanted you to see some of what was in the executable's metadata. He hopes you can see that the metadata contains all the information the runtime and compilers need about the assembly and its modules, types, and members, such as methods.

Class metadata

If you double-click the MyApp class in the main ILDASM window, you'll see the two methods of the MyApp class: the constructor and Main. You'll also see metadata for the class.

In this case, the class metadata indicates (when you double-click it) that MyApp is inherited from System.Object, which is part of the mscorlib assembly:

.class public auto ansi MyApp
       extends [mscorlib]System.Object
{
} // end of class MyApp

The IL code

If you double-click Main, you'll see its IL:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 
01 00 00 00 ) 
  // Code size       17 (0x11)
  .maxstack  8
  IL_0000:  ldstr      "Hello world! (pause) (from VB .NET)"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  call       string [mscorlib]System.Console::ReadLine()
  IL_000f:  pop
  IL_0010:  ret
} // end of method MyApp::Main

Note that the IL is simple: The call to Console.WriteLine consists of pushing a pointer to a string on the stack and calling the method. Similarly, the call to ReadLine is simple—note that the return value is popped from the stack after the call (and then ignored). Finally, Main returns to its caller. You can also see that Main is declared as the entry point.

The IL for the constructor is equally simple:

.method public specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method MyApp::.ctor

The ldarg.0 instruction copies the Me (this in C#) pointer passed to this constructor as an argument and calls the base class (System.Object) constructor.

Now do a swap...

Next, follow the steps just described, starting with the Give It a Shot! section on the SwapInts program shown earlier—create the source file, compile it, and run it. Take a look at the metadata and note the parameter information about the Swap function. Also, take a look at the IL code for both the call to Swap and the Swap function.

In the IL code for Main, you'll notice some box instructions. Because Console.WriteLine takes objects, not integers, as its arguments after the formatting string, the integers must be converted to objects. The conversion of a non-object type to an object is called boxing, and it's done in IL with the box instruction.

And let's try it with ASP.NET!

Next, let's look at one of our ASP.NET programs. If you haven't run your ASP.NET program yet, please do so now using the directions in the Hello World in ASP.NET section. The good doctor recommends you set up and run the Web swap Visual Basic program.

The first problem when you want to look at an ASP.NET assembly can be finding it: If you deal with your files by hand, as we're doing here, ASP.NET automatically compiles your code and puts the resulting assembly into a cache directory. We'll discuss in this column how to find the cache directory and your assembly.

If you're using Visual Studio .NET to create and build your program, it's easy to find the assembly. When Visual Studio builds your project, it creates a BIN directory inside your Web application's IIS directory and puts the compiled assembly there.

If you're not using Visual Studio and are using the SRC attribute to tell ASP.NET where to find the source code, ASP.NET will put it in its cache directory. (And ASP.NET puts the assembly for the Web page itself in this cache directory in any case.)

The easiest (and most reliable) way to find the file is to search for the source file name of the Visual Basic or C# file (such as "webswapvb.vb"). Make sure you search system folders.

You'll find a file with a name comprised of the source file name, followed by some extra stuff, and an .xml extension, such as webswapvb.vb.dbed68e8.xml. This file contains the base name of the assembly. Open the directory containing the .xml file, and then open the file itself in Notepad. The first thing you'll see in the file is a PRESERVE tag with an ASSEM attribute. That value of that attribute is the base name of the assembly DLL. You'll find the DLL in the same directory, so run ILDASM on it.

You'll also notice some similar .xml files whose names begin with the name of the .aspx file. You can use those files to find the assemblies into which the .aspx page is compiled, and then you can use ILDASM to look at those assemblies. In them you'll find a namespace called ASP; inside that namespace you'll find your class generated by ASP.NET and named for your .aspx page.

If the .aspx page has inline code, the page class will be derived from System.Web.UI.Page and will contain, among other things, a method that corresponds with each of the methods embedded in the .aspx page.

If the .aspx page uses code behind, the page class will be derived from your code-behind class (which is, in turn, derived from System.Web.UI.Page) and the methods will be in the assembly associated with your code.

The good doctor mentioned earlier that the very simple call to Swap in the Visual Basic program generates a lot of code, and he promised he'd show it. The source code is simple (one line: Swap(I.Text, J.Text)) but that one line generates a huge amount of code. Here it is:

.method private instance void  Button1_Click(object sender,
 class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       52 (0x34)
  .maxstack  2
  .locals init (string V_0,
           class [System.Web]System.Web.UI.WebControls.TextBox V_1,
           string V_2,
           class [System.Web]System.Web.UI.WebControls.TextBox V_3)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class [System.Web]System.Web.UI.WebControls.TextBox_
 SwapWebFormVb::I
  IL_0006:  stloc.3
  IL_0007:  ldloc.3
  IL_0008:  callvirt   instance string_ 
[System.Web]System.Web.UI.WebControls.TextBox::get_Text()
  IL_000d:  stloc.2
  IL_000e:  ldloca.s   V_2
  IL_0010:  ldarg.0
  IL_0011:  ldfld      class [System.Web]System.Web.UI.WebControls.TextBox_ 
SwapWebFormVb::J
  IL_0016:  stloc.1
  IL_0017:  ldloc.1
  IL_0018:  callvirt   instance string_ 
[System.Web]System.Web.UI.WebControls.TextBox::get_Text()
  IL_001d:  stloc.0
  IL_001e:  ldloca.s   V_0
  IL_0020:  call       void SwapWebFormVb::Swap(string&,
                                                string&)
  IL_0025:  ldloc.1
  IL_0026:  ldloc.0
  IL_0027:  callvirt   instance void_ 
[System.Web]System.Web.UI.WebControls.TextBox::set_Text(string)
  IL_002c:  ldloc.3
  IL_002d:  ldloc.2
  IL_002e:  callvirt   instance void_ 
[System.Web]System.Web.UI.WebControls.TextBox::set_Text(string)
  IL_0033:  ret
} // end of method SwapWebFormVb::Button1_Click

Have fun looking at your ASP.NET programs!

Finding What You Need in the Docs

There's a tremendous amount of documentation included with Visual Studio .NET and the .NET Framework SDK. But finding what you need can sometimes be a challenge, because there are three overlapping sets of documentation—MSDN Online, the .NET SDK documentation, and Visual Studio .NET documentation. Most of the documentation is in all of the sets, but you'll often find things in different places within the different sets.

MSDN Online

You can access MSDN Online documentation from any machine that's connected to the Internet. To find the information you're likely to need for .NET Framework programming, you'll need to use the .NET Development link on the right of the MSDN home page. This takes you to the .NET Framework Developer Center.

Under the .NET Development top-level node on the left, you'll find the Visual Studio .NET node and the .NET Framework SDK node, which contains the .NET Framework node. Under the .NET Framework node, you'll find most of the documentation for the Framework itself. You can find language references under .NET Development\.NET Framework SDK\.NET Framework\Reference\Compiler and Language Reference. And this is the only place you can find up-to-date versions of Dr. GUI .NET 1.1 (look under .NET Development\.NET Development (General)\Columns\Dr. GUI .NET).

.NET Framework SDK documentation

When you install the .NET Framework SDK (or when Visual Studio .NET Setup installs it for you), you'll find links to all of the docs on your Start menu under .NET Framework SDK v 1.1. The Overview link is a great place to start—it's the only place that includes links to all of the documentation, even the Tool Developer's Guide (with the IL instruction reference as part of the ECMA specification). Note that the only way to get to the Tool Developer's Guide pages is through this overview. But the .NET Framework SDK documentation doesn't have information about how to use Visual Studio itself.

On your Start menu, if you click the .NET Framework SDK v 1.1/Documentation icon, you'll get the .NET Framework SDK Help file. This file contains basically the same nodes of documentation as the .NET Development\.NET Framework SDK\Product Documentation\ node in MSDN Online and the .NET Framework node in Visual Studio .NET.

Web Matrix documentation

Web Matrix takes a different approach to documentation: Instead of including the documentation in Web Matrix, it just contains links to the appropriate documentation sets on the Internet. Any time you ask for help, Web Matrix fires up Internet Explorer and loads a page—and almost all of the pages come from a live Internet site.

The advantage of this is that the Web Matrix download can be smaller because documentation doesn't have to be included. The disadvantage is that you won't have access to the docs through Web Matrix if you don't have a working connection to the Internet at the moment.

What if you want to work while you're not connected? Actually, it's easy: Just download the .NET Framework SDK and use the documentation in it. Except for documentation on how to use Web Matrix itself, everything you'll need is in the .NET Framework SDK docs.

Or just buy one of the Visual language products or Visual Studio and get it all.

Visual Studio .NET documentation

Finally, if you've bought and installed Visual Studio, you can get at the documentation from inside the IDE. The Visual Studio docs have all of the information on how to use Visual Studio, plus almost all of the information just mentioned. You'll be able to get at language documentation from either the .NET Framework SDK node or the individual language node under the main Visual Studio .NET node.

Note that the MSDN Library node is missing the .NET Development node (as well as the Networking and Directory Services, XML Web services, and MSDN Archive nodes). Most of that information is under the Visual Studio .NET node, but some (like the revised Dr. GUI .NET 1.1) is only available online.

Documentation summary

Sometimes finding what you need in the documentation can be a bit challenging. There's some information that's only available online, and some that's only available in the .NET Framework SDK (which everyone who programs for the .NET Framework should have, either stand-alone or installed with Visual Studio .NET). Like any big new doc set, it takes a little time to get used to it. In general, though, Visual Studio has the most complete set (less the Tool Developer's Guide and the MSDN Online nodes just mentioned).

So, spend a little time browsing through the docs to see what's included—you'll be amazed at how much stuff there is!

Doing More on Your Own...

If you've got a little extra time, modify the programs you have here to do something that's interesting to you, run them, and examine them with ILDASM. To help with that, use the documentation. You'll especially want to take a look at the following sections:

  • Samples and Walkthroughs under Visual Studio .NET in the Visual Studio Help system
  • Quickstarts under the .NET Framework SDK node in all documentation sets systems
  • Compiler and Language Reference
  • .NET Framework Reference
  • .NET Framework Developer's Guide (on the Start menu, use the.NET Framework SDK v 1.1\Overview)
  • IL Instruction Reference (To find "Partition III CIL," from your Start menu, on the .NET Framework SDK Overview page, click the Tool Developers Guide, and then click Documentation.)

Join Us!

As mentioned earlier, there's a Dr. GUI .NET message board (or forum) hosted by GotDotNet for readers of this column. It's at http://gotdotnet.com/community/messageboard/MessageBoard.aspx?id=46. Here you can ask questions about and discuss this column, and you'll find the code. Please join in, ask your questions, and share what you've learned with others!

Where to Learn More

If you really want to get a leg up on .NET quickly, do some reading or take a course. Dr. GUI took an excellent course from author Jeffrey Richter of Wintellect (http://www.wintellect.com/). Jeff really knows his stuff and how to explain it well, and the good doctor benefited greatly from Jeff's course—as did this series of articles. (Dr. GUI admits, however, he's jealous that Jeff got to work in the same building as the .NET runtime team and Dr. GUI didn't.) Other companies, such as DevelopMentor, also offer courses and resources.

Jeff's book, Applied Microsoft .NET Framework Programming, is especially good. It comes in two versions—one for C#, one for Visual Basic .NET (https://microsoft.com/mspress/books/6199.asp). It's focused on the Framework and execution environment and really gives you the background you need to deeply understand what's going on. Dr. GUI got to review this book before it was published and heartily recommends it. It's really excellent. Its only shortcoming is that it's not been updated for the version 1.1 .NET Framework.

If you're interested in the ins and outs of IL language, check out Inside Microsoft .NET IL Assembler by Serge Lidin at https://microsoft.com/mspress/books/5771.asp.

There's a huge variety of books nowadays, including printed versions of the reference documentation (FINALLY!). Check out all of Microsoft Press's offerings at https://www.microsoft.com/mspress/net/framework/.

There is also a set of .NET mailing lists, and a new set of Microsoft newsgroups. The DevelopMentor mailing lists are very busy, but you can browse the archives on the Web.

You'll also want to visit the MSDN .NET Developer Center regularly to keep up to date on .NET and resources for learning about it.

And you'll want to regularly check out the GotDotNet Web site by the .NET Framework Development Team.

What We've Done; What's Next

This time we talked a bit about what .NET is—specifically about the .NET Framework and the runtime—and why you might care. We also talked about how to get and install the .NET Framework SDK and/or Visual Studio .NET, and ran through a couple of simple programs at the command line and in ASP.NET. Finally, we took a look at the metadata and IL for these programs, and spent a little time looking through the documentation.

It's been a long article, but Dr. GUI promises that future articles will be shorter. Really.

Next time, we're going to discuss the basic unit of the .NET Framework—types—as we do a brief review of object-oriented programming, including new features the .NET Framework provides.