Chapter 14: Visual Studio 2005


At this point you should be familiar with the C# language and almost ready to move on to the applied sections of the book, which look at how to use C# to program a variety of applications. Before doing that, however, you need to examine how you can use Visual Studio and some of the features provided by the .NET environment to get the best from your programs.

This chapter looks at what programming in the .NET environment means in practice. It covers Visual Studio, the main development environment in which you will write, compile, debug, and optimize your C# programs, and provides guidelines for writing good applications. Visual Studio is the main IDE used for everything from writing Web Forms and Windows Forms to XML Web services, and more. For more details on Windows Forms and how to write user interface code, see Chapter 28, “Windows Forms.”

This chapter also looks at what it takes to build applications that are targeted at the .NET Framework 3.0. The types of applications provided through the .NET Framework 3.0 class library include the Windows Presentation Foundation (WPF), the Windows Communication Foundation (WCF), and the Windows Workflow Foundation (WF).

Working with Visual Studio 2005

Visual Studio 2005 is a fully integrated development environment. It is designed to make the process of writing your code, debugging it, and compiling it to an assembly to be shipped as easy as possible. What this means in practice is that Visual Studio gives you a very sophisticated multiple-document-interface application in which you can do just about everything related to developing your code. It offers these features:

  • Text editor - Using this editor, you can write your C# (as well as Visual Basic 2005, J#, and C++) code. This text editor is quite sophisticated. For example, as you type, it automatically lays out your code by indenting lines, matching start and end brackets of code blocks, and color-coding keywords. It also performs some syntax checks as you type and underlines code that causes compilation errors, also known as design-time debugging. In addition it features IntelliSense, which automatically displays the names of classes, fields, or methods as you begin to type them. As you start typing parameters to methods, it will also show you the parameter lists for the available overloads. Figure 14-1 shows the IntelliSense feature in action with one of the .NET base classes, ListBox.

    image from book
    Figure 14-1

    Important 

    A useful shortcut to remember is that by pressing Ctrl+Space, you can bring back the IntelliSense list box if you need it and if for any reason it’s not visible.

  • Design view editor - This editor enables you to place user-interface and data-access controls in your project; Visual Studio automatically adds the necessary C# code to your source files to instantiate these controls in your project. (This is possible because all .NET controls are instances of particular base classes.)

  • Supporting windows - These windows allow you to view and modify aspects of your project, such as the classes in your source code as well as the available properties (and their startup values) for Windows Forms and Web Forms classes. You can also use these windows to specify compilation options, such as which assemblies your code needs to reference.

  • The ability to compile from within the environment - Instead of having to run the C# compiler from the command line, you can simply select a menu option to compile the project and Visual Studio will call the compiler for you and pass all the relevant command-line parameters to the compiler, detailing such things as which assemblies to reference and what type of assembly you want to be emitted (executable or library .dll, for example). If you want, it can also run the compiled executable for you so you can see whether it runs satisfactorily. You can even choose between different build configurations (for example, a release or debug build).

  • Integrated debugger - It’s in the nature of programming that your code won’t run correctly the first time you try it. Or the second time. Or the third time. Visual Studio seamlessly links up to a debugger for you, allowing you to set breakpoints and watches on variables from within the environment.

  • Integrated MSDN help - Visual Studio enables you to access the MSDN documentation from within the IDE. For example, if you’re not sure of the meaning of a keyword while using the text editor, simply select the keyword and press the F1 key, and Visual Studio accesses MSDN to show you related topics. Similarly, if you’re not sure what a certain compilation error means, you can bring up the documentation for that error by selecting the error message and pressing F1.

  • Access to other programs - Visual Studio can also access a number of other utilities that allow you to examine and modify aspects of your computer or network, without your having to leave the developer environment. Among the tools available, you can check running services and database connections, look directly into your SQL Server tables, and even browse the Web using an Internet Explorer window.

If you’ve developed previously using C++ or Visual Basic, you will already be familiar with the relevant Visual Studio 6 version of the IDE, and many of the features in the preceding list will not be new to you. What is new in Visual Studio is that it combines all the features that were previously available across all Visual Studio 6 development environments. This means that whatever language you used in Visual Studio 6, you’ll find some new features in Visual Studio. For example, in the older Visual Basic environment, you could not compile separate debug and release builds. On the other hand, if you are coming to C# from a background of C++, much of the support for data access and the ability to drop controls into your application with a click of the mouse, which has long been part of the Visual Basic developer’s experience, will be new to you. In the C++ development environment drag-and-drop support is limited to the most common user-interface controls.

Tip 

C++ developers will miss two Visual Studio 6 features in Visual Studio 2005: edit-and-continue debugging and an integrated profiler. Visual Studio 2005 also does not include a full profiler application. Instead, you will find a number of .NET classes that assist with profiling in the System.Diagnostics namespace. The perfmon profiling tool is available from the command line (just type perfmon) and has a number of new .NET-related performance monitors.

Whatever your background, you will find the overall look of the Visual Studio 2005 developer environment has changed since days of Visual Studio 6 to accommodate the new features, the single cross-language IDE, and the integration with .NET. There are new menu and toolbar options, and many of the existing ones from Visual Studio 6 have been renamed. So, you’ll have to spend some time familiarizing yourself with the layout and commands available in Visual Studio 2005.

The differences between Visual Studio 2002/2003 and Visual Studio 2005 are a few nice additions that facilitate working in Visual Studio 2005. The biggest changes in Visual Studio 2005 include the ability to refactor code, which allows you to extract methods, globally rename variables, and perform other quick actions upon an entire project of code.

One of the biggest items to notice with your installation of Visual Studio 2005 is that this new IDE works with the .NET Framework 2.0. In fact, when you install Visual Studio 2005, you will also be installing the .NET Framework 2.0 if it isn’t already installed. Visual Studio 2005 is not built to work with version 1.0 or 1.1 of the .NET Framework, which means that if you still want to develop 1.0 or 1.1 applications, you will want to keep Visual Studio 2002 or 2003, respectively, installed on your machine. Installing Visual Studio 2005 installs a complete and new copy of Visual Studio and does not upgrade the previous Visual Studio 2002 or 2003 IDEs. The three copies of Visual Studio will then run side by side.

Note that if you attempt to open your Visual Studio 2002 or 2003 projects using Visual Studio 2005, the IDE will warn you that your solution will be upgraded to Visual Studio 2005 if you continue by popping up the Visual Studio Conversion Wizard (see Figure 14-2).

image from book
Figure 14-2

The upgrade wizard has been dramatically improved from Visual Studio 2003 to this newer one provided by Visual Studio 2005. This new wizard can make backup copies of the solutions that are being backed up (see Figure 14-3), and it can also back up solutions that are contained within source control.

image from book
Figure 14-3

It is also possible to have Visual Studio generate a conversion report for you in the conversion process’s final step. The report will then be viewable directly in the document window of Visual Studio. This report is illustrated (done with a simple conversion) in Figure 14-4.

image from book
Figure 14-4

Remember that you shouldn’t upgrade production solutions without testing your programs first in a staging environment to ensure that your application will not be affected by the changes between versions 1.0/1.1 and 2.0 of the .NET Framework. If you have version 3.0 of the .NET Framework installed, you will find that there is no conversion process needed to upgrade your applications from using .NET Framework 2.0 to version 3.0.

Because this is a professional-level book, it doesn’t look in detail at every feature or menu option available in Visual Studio 2005. Surely, you will be able to find your way around the IDE. The real aim of the Visual Studio coverage is to ensure that you are sufficiently familiar with the concepts involved when building and debugging a C# application that you can make the most of working with Visual Studio 2005. Figure 14-5 shows what your screen might look like when working in Visual Studio 2005. (Note that because the appearance of Visual Studio is highly customizable, the windows might not be in the same locations or different windows might be visible when you launch this development environment.)

image from book
Figure 14-5

The following sections take you through the process of creating, coding, and debugging a project, showing what Visual Studio can do to help you at each stage.

Creating a Project

Once you have installed Visual Studio 2005, you will want to start your first project. With Visual Studio, you rarely start with a blank file and then add C# code, in the way that you’ve been doing in the previous chapters in this book. (Of course, the option of asking for an empty application project is there if you really do want to start writing your code from scratch or if you are going to create a solution that will contain a number of projects.) Instead, the idea is that you tell Visual Studio roughly what type of project you want to create, and it will generate the files and C# code that provides a framework for that type of project. You then work by adding your code to this outline. For example, if you want to build a Windows GUI-interface-based application (or, in .NET terminology, a Windows Form), Visual Studio will start you off with a file containing C# source code that creates a basic form. This form is capable of talking to Windows and receiving events. It can be maximized, minimized, or resized; all you have to do is add the controls and functionality you want. If your application is intended to be a command-line utility (a console application), Visual Studio will give you a basic namespace, class, and a Main() method to start you off.

Last, but hardly least, when you create your project, Visual Studio also sets up the compilation options that you are likely to supply to the C# compiler - whether it is to compile to a command-line application, a library, or a Windows application. It will also tell the compiler which base class libraries you will need to reference (a Windows GUI application will need to reference many of the Windows.Forms-related libraries; a console application probably won’t). You can, of course, modify all these settings as you are editing, if you need to.

The first time you start Visual Studio, you will be presented with a blank IDE (see Figure 14-6). The Start Page is an HTML page that contains various links to useful Web sites and enables you to open existing projects or start a new project altogether.

image from book
Figure 14-6

Figure 14-6 shows the type of Start Page you get after you’ve used Visual Studio 2005; it includes a list of the most recently edited projects. You can just click one of these projects to open it again.

Selecting a Project Type

You can create a new project by selecting File image from book New Project from the Visual Studio menu. From there you will get the New Project dialog box (see Figure 14-7) - and your first inkling of the variety of different projects you can create.

image from book
Figure 14-7

Using this dialog box, you effectively select the initial framework files and code you want Visual Studio to generate for you, the type of compilation options you want, and the compiler you want to compile your code with - either the Visual C#, Visual Basic 2005, Visual J#, or Visual C++ compiler. You can immediately see the language integration that Microsoft has promised for .NET at work here! This particular example uses a C# console application.

Tip 

We don’t have space to cover all the various options for different types of projects here. On the C++ side, all the old C++ project types are there - MFC application, ATL project, and so on. On the Visual Basic 2005 side, the options have changed somewhat. For example, you can create a Visual Basic 2005 command-line application (Console Application), a .NET component (Class Library), a .NET control (Windows Control Library), and more. However, you cannot create an old-style COM-based control (the .NET control is intended to replace such ActiveX controls).

The following table lists all the options that are available to you under Visual C# Projects. Note that some other, more specialized C# template projects are available under the Other Projects option.

Open table as spreadsheet

If you choose/...

You get the C# code and compilation options to generate/...

Windows Application

A basic empty form that responds to events.

Class Library

A .NET class that can be called up by other code.

Windows Control Library

A .NET class that can be called up by other code and that has a user interface. (Like an old-style ActiveX control.)

ASP.NET Web Application

An ASP.NET-based Web site: ASP.NET pages and C# classes that generate the HTML response sent to browsers from those pages.

ASP.NET Web Service

A C# class that acts as a fully operational Web service.

ASP.NET Mobile Web Application

An application type that allows you to build ASP.NET pages that target mobile devices.

Web Control Library

A control that can be called up by ASP.NET pages, to generate the HTML code that gives the appearance of a control when displayed on a browser.

Console Application

An application that runs at the command-line prompt, or in a console window.

Windows Service

A service that runs in the background on Windows NT and Windows 2000.

Crystal Reports Windows Application

A project for creating a C# application with a Windows user interface and a sample Crystal Report.

SQL Server Project

A project for creating classes to use in SQL Server.

Pocket PC 2003 Application

A project for creating a .NET Compact Framework 2.0 forms application for Pocket PC 2003 and later.

Pocket PC 2003 Class Library

A project for creating a .NET Compact Framework 2.0 class library (.dll) for Pocket PC 2003 and later.

Pocket PC 2003 Control Library

A project for creating .NET Compact Framework 2.0 controls for Pocket PC 2003 and later.

Pocket PC 2003 Console Application

A project for creating a .NET Compact Framework 2.0 nongraphical application for Pocket PC 2003 and later.

Pocket PC 2003 Empty Project

An empty project for creating a .NET Compact Framework 2.0 application for Pocket PC 2003 and later.

Smartphone 2003 Application

A project for creating a .NET Compact Framework 1.0 forms application for Smartphone 2003 and later.

Smartphone 2003 Class Library

A project for creating .NET Compact Framework 1.0 class library (.dll) for Smartphone 2003 and later.

Smartphone 2003 Console Application

A project for creating a .NET Compact Framework 1.0 nongraphical application for Smartphone 2003 and later.

Smartphone 2003 Empty Project

An empty project for creating a .NET Compact Framework 1.0 application for Smartphone 2003 and later.

Windows CE 5.0 Application

A project for creating a .NET Compact Framework 2.0 forms application for Windows CE 5.0 and later.

Windows CE 5.0 Class Library

A project for creating a .NET Compact Framework 2.0 class library (.dll) for Windows CE 5.0 and later.

Windows CE 5.0 Control Library

A project for creating .NET Compact Framework 2.0 controls for Windows CE 5.0 and later.

Windows CE 5.0 Console Application

A project for creating a .NET Compact Framework 2.0 command-line application for Windows CE 5.0 and later.

Windows CE 5.0 Empty Project

An empty project for creating a .NET Compact Framework 2.0 application for Windows CE 5.0 and later.

Excel Workbook

A project for creating managed code extensions behind a new or existing Excel 2003 workbook.

Word Document

A project for creating managed code extensions behind a new or existing Word 2003 document.

Excel Template

A project for creating managed code extensions behind a new or existing Excel 2003 template.

Word Template

A project for creating managed code extensions behind a new or existing Word 2003 template.

Empty Project

Installs nothing. You have to write all your code from scratch, but you still get the benefit of all the Visual Studio facilities when you are writing.

Empty Web Project

The same as Empty Project, but the compilation settings are set to instruct the compiler to generate code for ASP.NET pages.

New Project In Existing Folder

New project files for an empty project. Use this option if you have some straight C# source code (for example, typed in a text editor) and want to turn it into a Visual Studio project.

This isn’t a full list and the .NET Framework 3.0 projects are reviewed later in this chapter. Various types of starter kits, such as a screen saver starter kit and a movie collection starter kit, are also available. Also, a test application is available that allows you to create a project that contains tests.

The Newly Created Console Project

When you click OK after selecting the Console Application option, Visual Studio gives you a couple of files, including a source code file, Program.cs, which contains the initial framework code. Figure 14-8 shows what code Visual Studio has written for you.

image from book
Figure 14-8

As you can see, you have a C# program that doesn’t do anything yet but contains the basic items required in any C# executable program: a namespace and a class that contains the Main() method, which is the program’s entry point. (Strictly speaking, the namespace isn’t necessary, but it would be very bad programming practice not to declare one.) This code is all ready to compile and run, which you can do immediately by pressing the F5 key or by selecting the Debug menu and choosing Start. However, before you do that, add the following line of code - to make your application actually do something!

 static void Main(string[] args) {    Console.WriteLine("Hello from all the folks at Wrox Press"); }

If you compile and run the project, you’ll see a console window that stays onscreen barely long enough so that you have time to read the message. The reason this happens is that Visual Studio, remembering the settings you specified when you created the project, arranged for it to be compiled and run as a console application. Windows then realizes that it has to run a console application but doesn’t have a console window to run it from. So, Windows creates a console window and runs the program. As soon as the program exits, Windows recognizes that it doesn’t need the console window anymore and promptly removes it. That’s all very logical but doesn’t help you very much if you actually want to look at the output from your project!

A good way to avoid this problem is to insert the following line just before the Main() method returns in your code:

 static void Main(string[] args) {    Console.WriteLine("Hello from all the folks at Wrox Press");    Console.ReadLine(); }

That way, your code will run, display its output, and come across the Console.ReadLine() statement, at which point it will wait for you to press the Return (or Enter) key before the program exits. This means that the console window will hang around until you press Return.

Note that all this is only an issue for console applications that you test-run from Visual Studio - if you are writing a Windows application, the window displayed by the application will automatically remain onscreen until you exit it. Similarly, if you run a console application from the command-line prompt, you won’t have any problems about the window disappearing.

Other Files Created

The Program.cs source code file isn’t the only file that Visual Studio has created for you. If you take a look in the folder in which you asked Visual Studio to create your project, you will see not just the C# file, but a complete directory structure that looks like what is shown in Figure 14-9.

image from book
Figure 14-9

The two folders, bin and obj, store compiled and intermediate files. Subfolders of obj hold various temporary or intermediate files; subfolders of bin hold the compiled assemblies.

Tip 

Traditionally, Visual Basic developers would simply write the code and then run it. Before shipping, the code would then have to be compiled into an executable; Visual Basic tended to hide the process of compilation when debugging. In C#, it’s more explicit: to run the code, you have to compile (or build) it first, which means that an assembly must be created somewhere.

The remaining files in the project’s main folder, ConsoleApplication1, are there for Visual Studio’s benefit. They contain information about the project (for example, the files it contains) so that Visual Studio knows how to have the project compiled and how to read it in the next time you open the project.

Solutions and Projects

One important distinction you must understand is that between a project and a solution:

  • A project is a set of all the source code files and resources that will compile into a single assembly (or in some cases, a single module). For example, a project might be a class library or a Windows GUI application.

  • A solution is the set of all the projects that make up a particular software package (application).

To understand this distinction, look at what happens when you ship a project - the project consists of more than one assembly. For example, you might have a user interface, custom controls, and other components that ship as libraries of the parts of the application. You might even have a different user interface for administrators. Each of these parts of the application might be contained in a separate assembly, and hence, they are regarded by Visual Studio as a separate project. However, it is quite likely that you will be coding these projects in parallel and in conjunction with each other. Thus, it is quite useful to be able to edit them all as one single unit in Visual Studio. Visual Studio allows this by regarding all the projects as forming one solution, and treats the solution as the unit that it reads in and allows you to work on.

Up until now we have been loosely talking about creating a console project. In fact, in the example you are working on, Visual Studio has actually created a solution for you - though this particular solution contains just one project. You can see the situation in a window in Visual Studio known as the Solution Explorer (see Figure 14-10), which contains a tree structure that defines your solution.

image from book
Figure 14-10

Figure 14-10 shows that the project contains your source file, Program.cs, as well as another C# source file, AssemblyInfo.cs (found in the Properties folder), which allows you to provide information that describes the assembly as well as the ability to specify versioning information. (You look at this file in detail in Chapter 16, “Assemblies.”) The Solution Explorer also indicates the assemblies that your project references according to namespace. You can see this by expanding the References folder in the Solution Explorer.

If you haven’t changed any of the default settings in Visual Studio, you will probably find the Solution Explorer in the top-right corner of your screen. If you can’t see it, just go to the View menu and select Solution Explorer.

The solution is described by a file with the extension .sln - in this example, it’s ConsoleApplication1 .sln. The project is described by various other files in the project’s main folder. If you attempt to edit these files using Notepad, you’ll find that they are mostly plain-text files, and, in accordance with the principle that .NET and .NET tools rely on open standards wherever possible, they are mostly in XML format.

Tip 

C++ developers will recognize that a Visual Studio solution corresponds to an old Visual C++ project workspace (stored in a .dsw file), and a Visual Studio project corresponds to an old C++ project (.dsp file). By contrast, Visual Basic developers will recognize that a solution corresponds to an old Visual Basic project group (.vbg file), and the .NET project corresponds to an old Visual Basic project (.vbp file). Visual Studio differs from the old Visual Basic IDE in that it always creates a solution for you automatically. In Visual Studio 6, Visual Basic developers would get a project; however, they would have to request a project group from the IDE separately.

Adding Another Project to the Solution

As you work through the following sections, you will see how Visual Studio works with Windows applications as well as console ones. To that end, you will create a Windows project called BasicForm that you will add to your current solution, ConsoleApplication1.

Tip 

This means that you’ll end up with a solution containing a Windows application and a console application. That’s not a very common scenario - you’re more likely to have one application and a number of libraries - but it allows you to see more code! You might, however, create a solution like this if, for example, you are writing a utility that you want to run either as a Windows application or as a command-line utility.

You can create the new project in two ways. You can select New Project from the File menu (as you’ve done already) or you can select Add image from book New Project from the File menu. If you select New Project from the File menu, this will bring up the familiar New Project dialog box; this time, however, you’ll notice that Visual Studio wants to create the new project in the preexisting ConsoleApplication1 project location (see Figure 14-11).

image from book
Figure 14-11

If you select this option, a new project is added so that the ConsoleApplication1 solution now contains a console application and a Windows application.

Tip 

In accordance with the language-independence of Visual Studio, the new project doesn’t have to be a C# project. It’s perfectly acceptable to put a C# project, a Visual Basic 2005 project, and a C++ project in the same solution. But we’ll stick with C# here since this is a C# book!

Of course, this means that ConsoleApplication1 isn’t really an appropriate name for the solution anymore! To change the name, you can right-click on the name of the solution and select Rename from the context menu. Call the new solution DemoSolution. The Solution Explorer window now looks like Figure 14-12.

image from book
Figure 14-12

You can see from this that Visual Studio has made your newly added Windows project automatically reference some of the extra base classes that are important for Windows Forms functionality.

You’ll notice if you look in Windows Explorer that the name of the solution file has changed to DemoSolution.sln. In general, if you want to rename any files, the Solution Explorer window is the best place to do so, because Visual Studio will then automatically update any references to that file in the other project files. If you just rename files using Windows Explorer, you might find you break the solution because Visual Studio won’t be able to locate all the files it needs to read in. You will then have to manually edit the project and solution files to update the file references.

Setting the Startup Project

One thing you’ll need to bear in mind if you have multiple projects in a solution is that only one of them can be run at a time! When you compile the solution, all the projects in it will be compiled. However, you have to specify which one is the one you want Visual Studio to start running when you press F5 or select Start. If you have one executable and several libraries that it calls, then this will clearly be the executable. In this case, where you have two independent executables in the project, you’d simply have to debug each in turn.

You can tell Visual Studio which project to run by right-clicking that project in the Solution Explorer window and selecting Set as Startup Project from the context menu. You can tell which one is the current startup project - it is the one that appears in bold in the Solution Explorer window (WindowsApplication1 in Figure 14-12).

Windows Application Code

A Windows application contains a lot more code right from the start than a console application when Visual Studio first creates it. That’s because creating a window is an intrinsically more complex process. Chapter 28, “Windows Forms,” discusses the code for a Windows application in detail. For now, take a look at the code in the Form1 class in the WindowsApplication1 project to see for yourself how much is auto-generated.

Reading in Visual Studio 6 Projects

If you are coding in C#, you won’t need to read in any old Visual Studio 6 projects because C# doesn’t exist in Visual Studio 6. However, language interoperability is a key part of the .NET Framework, so you might want your C# code to work alongside code written in Visual Basic or in C++. In that situation, you might have to edit projects that were created with Visual Studio 6.

Visual Studio has no problems reading in and upgrading Visual Studio 6 projects and workspaces. The situation is different for C++, Visual Basic, and J++ projects:

  • In Visual C++, no change to the source code is needed. All your old Visual C++ code still works fine with the new C++ compiler. Obviously, it is not managed code, but it will still compile to code that runs outside the .NET runtime; if you want your code to integrate with the .NET Framework, you will need to edit it. If you get Visual Studio to read in an old Visual C++ project, it will simply add a new solution file and updated project files. It will leave the old .dsw and .dsp files unchanged so that the project can still be edited by Visual Studio 6, if necessary.

  • In the case of Visual Basic, things are a bit more complicated. As mentioned in Chapter 1, “.NET Architecture,” although Visual Basic 2005 has been designed very much around Visual Basic 6.0 and shares much of the same syntax, it is in many ways a new language. In Visual Basic 6.0, the source code largely consisted of the event handlers for the controls. In Visual Basic 2005, the code that actually instantiates the main window and many of its controls is not part of Visual Basic but is instead hidden behind the scenes as part of the configuration of your project. In contrast, Visual Basic 2005 works in the same way as C#, by putting the entire program out in the open as source code, so all the code that displays the main window and all the controls on it needs to be in the source file. Also, like C#, Visual Basic 2005 requires everything to be object oriented and part of a class, whereas VB didn’t even recognize the concept of classes in the .NET sense. If you try to read a Visual Basic project with Visual Studio, it will have to upgrade the entire source code to Visual Basic 2005 before it can handle it - and this involves making a lot of changes to the Visual Basic code. Visual Studio can, to a large extent, make these changes automatically and will then create a new Visual Basic 2005 solution for you. You will find that the source code it gives you looks very different from the corresponding Visual Basic code, and you will still need to check carefully through the generated code to make sure that the project still works correctly. You might even find areas in the code where Visual Studio has left comments to the effect that it can’t figure out exactly what you wanted the code to do, and you might have to edit the code manually.

  • As far as Microsoft is concerned, J++ is now an obsolete language and is not directly supported in .NET. However, in order that existing J++ code can continue to operate, separate tools are available to allow J++ code to work with .NET. Visual Studio 2005 includes the J# development environment and will work with J++ code. There is also a utility that can convert legacy J++ code to C# code - similar to the Visual Basic 6 to Visual Basic 2005 upgrade facility. These tools are grouped under the name JUMP (Java User Migration Path) and at the time of writing are neither bundled with .NET nor Visual Studio; you can download them instead at http://msdn.microsoft.com/vjsharp/jump/default.aspx.

Exploring and Coding a Project

This section looks at the features that Visual Studio provides to help you add code to your project.

The Folding Editor

One really exciting feature of Visual Studio is its use of a folding editor as its default code editor (see Figure 14-13).

image from book
Figure 14-13

Figure 14-13 shows the code for the console application that you generated earlier. Notice those little minus signs on the left-hand side of the window. These signs mark the points where the editor assumes that a new block of code (or documentation comment) begins. You can click these icons to close up the view of the corresponding block of code just as you would close a node in a tree control (see Figure 14-14).

image from book
Figure 14-14

This means that while you are editing you can focus on just the areas of code you want to look at, and you can hide the bits of code you’re not interested in. If you don’t like the way the editor has chosen to block off your code, you can indicate your own blocks of collapsing code with the C# preprocessor directives, #region and #endregion, which were examined earlier in the book. For example, if you wanted to collapse the code inside the Main() method, you would add the code shown in Figure 14-15.

image from book
Figure 14-15

The code editor will automatically detect the #region block and place a new minus sign by the #region directive, as shown in Figure 14-15, allowing you to close the region. Enclosing this code in a region means that you can get the editor to close the block of code (see Figure 14-16), marking the area with the comment you specified in the #region directive. The compiler, however, ignores the directives and compiles the Main() method as normal.

image from book
Figure 14-16

In addition to the folding editor feature, Visual Studio’s code editor brings across all the familiar functionality from Visual Studio 6. In particular it features IntelliSense, which not only saves you typing, but also ensures that you use the correct parameters. C++ developers will notice that the Visual Studio IntelliSense feature is a bit more robust than the Visual Studio 6 version and also works more quickly. You will also notice that IntelliSense has been improved in Visual Studio 2005. It is now smarter in that it remembers your preferred choices and starts off with one of these choices instead of starting directly at the beginning of the sometimes rather lengthy lists that IntelliSense can now provide.

The code editor also performs some syntax checking on your code and underlines most syntax errors with a short wavy line, even before you compile the code. Hovering the mouse pointer over the underlined text brings up a small box telling you what the error is. Visual Basic developers have been familiar with this feature, known as design-time debugging, for years; now C# and C++ developers can benefit from it as well.

Other Windows

In addition to the code editor, Visual Studio provides a number of other windows that allow you to view your project from different points of view.

Tip 

The rest of this section describes a number of other windows. If one of these windows is not visible on your screen, you can select it from the View menu. To show the design view and code editor, right-click the file name in the Solution Explorer and select View Designer or View Code from the context menu, or select the item from the toolbar at the top of the Solution Explorer. The design view and code editor share the same tabbed window.

The Design View Window

If you are designing a user interface application, such as a Windows application, Windows control library, or an ASP.NET application, you will use the Design View window. This window presents a visual overview of what your form will look like. You normally use the Design View window in conjunction with a window known as the toolbox. The toolbox contains a large number of .NET components that you can drag onto your program (see Figure 14-17).

image from book
Figure 14-17

The principle of the toolbox was applied in all development environments in Visual Studio 6, but with .NET the number of components available from the toolbox has vastly increased. The categories of components available through the toolbox depend, to some extent, on the type of project you are editing - for example, you’ll get a far wider range when you are editing the WindowsApplication1 project in the DemoSolution solution than you will when you are editing the ConsoleApplication1 project. The most important ranges of items available include the following:

  • Data - Classes that allow you to connect to data sources and manage the data they contain. Here you will find components for working with Microsoft SQL Server, Oracle, and any OleDb data source.

  • Windows Forms Controls (labeled as Common Controls) - Classes that represent visual controls such as text boxes, list boxes, or tree views for working with thick-client applications.

  • Web Forms Controls (labeled as Standard) - Classes that basically do the same thing as Windows controls, but that work in the context of Web browsers, and that work by sending HTML output to simulate the controls to the browser.

  • Components - Miscellaneous .NET classes that perform various useful tasks on your machine, such as connecting to directory services or to the event log.

You can also add your own custom categories to the toolbox by right-clicking on any category and selecting Add Tab from the context menu. You can also place other tools in the toolbox by selecting Choose Items from the same context menu - this is particularly useful for adding your favorite COM components and ActiveX controls, which are not present in the toolbox by default. If you add a COM control, you can still click to place it in your project just as you would with a .NET control. Visual Studio automatically adds all the required COM interoperability code to allow your project to call up the control. In this case, what is actually added to your project is a .NET control that Visual Studio creates behind the scenes and that acts as a wrapper for your COM control.

Tip 

C++ developers will recognize the toolbox as Visual Studio’s (much enhanced) version of the resource editor. Visual Basic developers might not be that impressed at first; after all, Visual Studio 6 also has a toolbox. However, the toolbox in Visual Studio has a dramatically different effect on your source code than its precursor.

To see how the toolbox works, place a text box in your basic form project. You simply click the TextBox control contained within the toolbox and then click again to place it in the form in the design view (or if you prefer, you can simply drag and drop the control directly onto the design surface). Now the design view looks like Figure 14-18, showing roughly what WindowsApplication1 will look like if you compile and run it.

image from book
Figure 14-18

If you look at the code view of your form, you see that Visual Studio 2005 doesn’t add the code that instantiates a TextBox object to go on the form directly here as it did in previous versions of the IDE. Instead, you will need to expand the plus sign next to Form1.cs in the Visual Studio Solution Explorer. Here you will find a file that is dedicated to the design of the form and the controls that are placed on the form - Form1.Designer.cs. In this class file, you will find a new member variable in the Form1 class:

 partial class Form1 {    private System.Windows.Forms.TextBox textBox1; 

There is also some code to initialize it in the method, InitializeComponent(), which is called from the Form1 constructor:

  /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() {    this.textBox1 = new System.Windows.Forms.TextBox();    this.SuspendLayout();    //    // textBox1    //    this.textBox1.Location = new System.Drawing.Point(13, 13);    this.textBox1.Name = "textBox1";    this.textBox1.Size = new System.Drawing.Size(100, 20);    this.textBox1.TabIndex = 0;    //    // Form1    //    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;    this.ClientSize = new System.Drawing.Size(292, 273);    this.Controls.Add(this.textBox1);    this.Name = "Form1";    this.Text = "Form1";    this.ResumeLayout(false);    this.PerformLayout(); } 

In one sense, there is no difference between the code editor and the design view; they simply present different views of the same code. What actually happened when you clicked to add the TextBox to the design view is that the editor placed the preceding extra code in your C# source file for you. The design view simply reflects this change because Visual Studio is able to read your source code and determine from it what controls should be around when the application starts up. This is a fundamental shift from the old Visual Basic way of looking at things, in which everything was based around the visual design. Now, your C# source code is what fundamentally controls your application, and the design view is just a different way of viewing the source code. Incidentally, if you do write any Visual Basic 2005 code with Visual Studio, you’ll find the same principles at work.

If you’d wanted to, you could have worked the other way around. If you manually added the same code to your C# source files, Visual Studio would have automatically detected from the code that your application contained a TextBox control, and would have shown it in the design view at the designated position. It is best to add these controls visually, and let Visual Studio handle the initial code generation - it’s a lot quicker and less error-prone to click the mouse button a couple of times than to type a few lines of code!

Another reason for adding these controls visually is that, to recognize that they are there, Visual Studio does need the relevant code to conform to certain criteria - and code that you write by hand might not do so. In particular, you’ll notice that the InitializeComponent() method that contains the code to initialize the TextBox is commented to warn you against modifying it. That’s because this is the method that Visual Studio looks at in order to determine what controls are around when your application starts up. If you create and define a control somewhere else in your code, Visual Studio won’t be aware of it, and you won’t be able to edit it in the design view or certain other useful windows.

In fact, despite the warnings, you can modify the code in InitializeComponent(), provided that you are careful. There’s generally no harm in changing the values of some of the properties, for example, so that a control displays different text or so that it is a different size. In practice, the developer studio is pretty robust when it comes to working around any other code you place in this method. Just be aware that if you make too many changes to InitializeComponent(), you do run the risk that Visual Studio won’t recognize some of your controls. We should stress that this won’t affect your application in any way whatsoever when it is compiled, but it might disable some of the editing features of Visual Studio for those controls. Hence, if you want to add any other substantial initialization, it’s probably better to do so in the Form1 constructor or in some other method.

The Properties Window

This is another window that has its origins in the old Visual Basic IDE. You know from the first part of the book that .NET classes can implement properties. In fact, as you’ll discover when building Windows Forms (see Chapter 28, “Windows Forms”), the .NET base classes that represent forms and controls have a lot of properties that define their action or appearance - properties such as Width, Height, Enabled (whether the user can type input to the control), and Text (the text displayed by the control) - and Visual Studio knows about many of these properties. The Properties window, shown in Figure 14-19, displays and allows you to edit the initial values of most of these properties for the controls that Visual Studio has been able to detect by reading your source code.

image from book
Figure 14-19

Important 

The Properties window can also show events. You can view events for what you are focused on in the IDE or selected in the drop-down list box directly in the Properties window by clicking the icon that looks like a lightning bolt at the top of the window.

At the top of the Properties window is a list box that allows you to select which control you want to view. In the example in this chapter, you’ve selected Form1, the main form class for your WindowsApplication1 project, and have edited the text to “Basic Form - Hello!” If you now check the source code, you can see that what you have actually done is edit the source code - using a friendlier user interface:

 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 273); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Basic Form - Hello"; this.ResumeLayout(false); this.PerformLayout();

Not all the properties shown in the Properties window are explicitly mentioned in your source code. For those that aren’t, Visual Studio will display the default values that were set when the form was created and that are set when the form is actually initialized. Obviously, if you change a value for one of these properties in the Properties window, a statement explicitly setting that property will magically appear in your source code - and vice versa. It is interesting to note that if a property is changed from its original value, this property will then appear in bold type within the list box of the Properties window. Sometimes double-clicking the property in the Properties window returns the value to its original value.

The Properties window provides a convenient way to get a broad overview of the appearance and properties of a particular control or window.

Tip 

It is interesting to note that the Properties window is implemented as a System.Windows.Forms .PropertyGrid instance, which will internally use the reflection technology described in Chapter 12, “Reflection,” to identify the properties and property values to display.

The Class View Window

Unlike the Properties window, the Class View window, shown in Figure 14-20, owes its origins to the C++ (and J++) developer environments. This window will be new to Visual Basic developers because Visual Basic 6 did not even support the concept of the class, other than in the sense of a COM component. The class view is not actually treated by Visual Studio as a window in its own right - rather it is an additional tab to the Solution Explorer window. By default, the class view will not even appear in the Visual Studio Solution Explorer. To invoke the class view, select View image from book Class View. The class view (see Figure 14-20) shows the hierarchy of the namespaces and classes in your code. It gives you a tree view that you can expand to see what namespaces contain what classes and what classes contain what members.

image from book
Figure 14-20

A nice feature of the class view is that if you right-click the name of any item for which you have access to the source code, the context menu features the Go To Definition option, which takes you to the definition of the item in the code editor. Alternatively, you can do this by double-clicking the item in class view (or, indeed, by right-clicking the item you want in the source code editor and choosing the same option from the resulting context menu). The context menu also gives you the option to add a field, method, property, or indexer to a class. This means that you specify the details of the relevant member in a dialog box, and the code gets added for you. This might not be that useful in the case of fields or methods, which can be quickly added to your code; however, you might find this feature helpful in the case of properties and indexers, where it can save you quite a bit of typing.

The Object Browser Window

One important aspect of programming in the .NET environment is being able to find out what methods and other code items are available in the base classes and any other libraries that you are referencing from your assembly. This feature is available through a window called the Object Browser. You can access this window by selecting Object Browser from the View menu in Visual Studio 2005.

The Object Browser window is quite similar to the Class View window in that it displays a tree view that gives the class structure of your application, allowing you to inspect the members of each class. The user interface is slightly different in that it displays class members in a separate pane rather than in the tree view itself. The real difference is that it lets you look at not just the namespaces and classes in your project but also the ones in all the assemblies referenced by the project. Figure 14-21 shows the Object Browser viewing the SystemException class from the .NET base classes.

image from book
Figure 14-21

The only point you have to watch with the Object Browser is that it groups classes by the assembly in which they are located first and by namespace second. Unfortunately, because namespaces for the base classes are often spread across several assemblies, this means you might have trouble locating a particular class unless you know what assembly it is in.

The Object Browser is there to view .NET objects. If for any reason you want to investigate installed COM objects, you’ll find that the OLEView tool previously used in the C++ IDE is still available - it’s located in the folder C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin along with several other similar utilities.

Tip 

Visual Basic developers should not confuse the .NET Object Browser with the Object Browser of the Visual Basic 6 IDE. The .NET Object Browser is there to view .NET classes, whereas the tool of that name in Visual Basic 6 is used to view COM components. If you want the functionality of the old Object Browser, you should now use the OLEView tool.

The Server Explorer window

You can use the Server Explorer window, shown in Figure 14-22, to find out about aspects of the computers in your network while coding.

image from book
Figure 14-22

As you can see from the screenshot, among the things you can access through the Server Explorer are database connections, information about services, event logs, and more.

The Server Explorer is linked to the Properties window so that if you open the Services node, for example, and click a particular service, the properties of that service will be displayed in the Properties window.

Pin Buttons

While exploring Visual Studio, you might have noticed that many of the windows have some interesting functionality more reminiscent of toolbars. In particular, apart from the code editor, they can all be docked. Another, very new, feature of them is that when they are docked, they have an extra icon that looks like a pin next to the minimize button in the top-right corner of each window. This icon really does act like a pin - it can be used to pin the windows open. When they are pinned (the pin is displayed vertically), they behave just like the regular windows that you are used to. When they are unpinned, however (the pin is displayed horizontally), they only remain open as long as they have the focus. As soon as they lose the focus (because you clicked or moved your mouse somewhere else) they smoothly retreat into the main border around the entire Visual Studio application. (You can also feel the speed of your computer by how fast or slow they open and close).

Pinning and unpinning windows provides another way of making the best use of the limited space on your screen. It’s not really been seen a great deal in Windows before, though a few third-party applications such as PaintShop Pro have used similar concepts. Pinned windows have, however, been around on many Unix-based systems for quite a while.

Building a Project

This section examines the options that Visual Studio gives you for building your project.

Building, Compiling, and Making

Before examining the various build options, it’s important to clarify some terminology. You’ll often see three different terms used in connection with the process of getting from your source code to some sort of executable code: compiling, building, and making. The origin of these various terms comes from the fact that until recently, the process of getting from source code to executable code involved more than one step (and this is still the case in C++). This was due in large part to the number of source files in a program. In C++, for example, each source file needs to be compiled individually. This leads to what are known as object files, each containing something like executable code, but where each object file relates to only one source file. In order to generate an executable, these object files need to be linked together, a process that is officially known as linking. The combined process was usually referred to - at least on the Windows platform - as building your code. However, in C# terms the compiler is more sophisticated and is able to read in and treat all your source files as one block. Hence, there isn’t really a separate linking stage, so in the context of C# the terms compile and build are used interchangeably.

In addition to this, the term make basically means the same as build, though it’s not really used in the context of C#. The term originated on old mainframe systems on which, when a project was composed of many source files, a separate file would be written that contained instructions to the compiler on how to build a project - which files to include and what libraries to link to and so on. This file was generally known as a make file and is still quite standard on Unix systems. Make files are not normally needed on Windows, though you can still write them (or get Visual Studio to generate them) if you need to.

Debug and Release Builds

The idea of having separate builds is very familiar to C++ developers and less so to those with a Visual Basic background. The point here is that when you are debugging you typically want your executable to behave differently than it does when you are ready to ship the software. When you are ready to ship your software, you want the size of the executable to be as small as possible and the executable itself to be as fast as possible. Unfortunately, these requirements aren’t really compatible with your needs when you are debugging code, as explained in the following sections.

Optimization

High performance is achieved partly by the compiler doing a lot of optimizations on the code. This means that the compiler actively looks at your source code as it’s compiling in order to identify places where it can modify the precise details of what you’re doing in a way that doesn’t change the overall effect but that makes things more efficient. For example, if the compiler encountered the following source code:

  double InchesToCm(double Ins) {    return Ins*2.54; } // later on in the code Y = InchesToCm(X); 

it might replace it with this:

  Y = X * 2.54; 

Or it might replace this code:

  {    string Message = "Hi";    Console.WriteLine(Message); } 

with this:

  Console.WriteLine("Hi"); 

By doing so, it bypasses having to declare an unnecessary object reference in the process.

It’s not possible to exactly pin down what optimizations the C# compiler does - nor whether the two previous examples actually would occur with any particular example, because those kinds of details are not documented (chances are that for managed languages such as C#, the previous optimizations would occur at JIT compilation time, not when the C# compiler compiles source code to assembly). For obvious commercial reasons, companies that write compilers are usually quite reluctant to give too many details about the tricks that their compilers use. We should stress that optimizations do not affect your source code - they affect only the contents of the executable code. However, the previous examples should give you a good idea of what to expect from optimizations.

The problem is that although optimizations like the previous ones help a great deal in making your code run faster, they aren’t that helpful for debugging. Suppose with the first example that you want to set a break-point inside the InchesToCm() method to see what’s going on in there. How can you possibly do that if the executable code doesn’t actually have an InchesToCm() method because the compiler has removed it? And how can you set a watch on the Message variable when that doesn’t exist in the compiled code either?

Debugger Symbols

When you’re debugging, you often have to look at values of variables, and you will specify them by their source code names. The trouble is that executable code generally doesn’t contain those names - the compiler replaces the names with memory addresses. .NET has modified this situation somewhat, to the extent that certain items in assemblies are stored with their names, but this is only true of a small minority of items - such as public classes and methods - and those names will still be removed when the assembly is JIT-compiled. Asking the debugger to tell you what the value is in the variable called HeightInInches isn’t going to get you very far if, when the debugger examines the executable code, it sees only addresses and no reference to the name HeightInInches anywhere. So, to debug properly, you need to have extra debugging information made available in the executable. This information includes, among other things, names of variables and line information that allows the debugger to match up which executable machine assembly language instructions correspond to those of your original source code instructions. You won’t, however, want that information in a release build, both for commercial reasons (debugging information makes it a lot easier for other people to disassemble your code) and because it increases the size of the executable.

Extra Source Code Debugging Commands

A related issue is that quite often while you are debugging there will be extra lines in your code to display crucial debugging-related information. Obviously, you want the relevant commands removed entirely from the executable before you ship the software. You could do this manually, but wouldn’t it be so much easier if you could simply mark those statements in some way so that the compiler ignores them when it is compiling your code to be shipped? You’ve already seen in the first part of the book how this can be done in C# by defining a suitable processor symbol, and possibly using this in conjunction with the Conditional attribute, giving you what is known as conditional compilation.

What all these factors add up to is that you need to compile almost all commercial software in a slightly different way when debugging than in the final product that is shipped. Visual Studio is able to take this into account because, as you have already seen, it stores details of all the options that it is supposed to pass to the compiler when it has your code compiled. All that Visual Studio has to do in order to support different types of builds is to store more than one set of such details. The different sets of build information are referred to as configurations. When you create a project, Visual Studio automatically gives you two configurations, called Debug and Release:

  • The Debug configuration commonly specifies that no optimizations are to take place, extra debugging information is to be present in the executable, and the compiler is to assume that the debug preprocessor symbol Debug is present unless it is explicitly #undefined in the source code.

  • The Release configuration specifies that the compiler should optimize, that there should be no extra debugging information in the executable, and that the compiler should not assume that any particular preprocessor symbol is present.

You can define your own configurations as well. You might want to do this, for example, if you want to set up professional-level builds and enterprise-level builds so you can ship two versions of the software. In the past, because of issues concerning the Unicode character encodings being supported on Windows NT but not on Windows 95, it was common for C++ projects to feature a Unicode configuration and an MBCS (multibyte character set) configuration.

Selecting a Configuration

One obvious question is that, because Visual Studio stores details of more than one configuration, how does it determine which one to use when arranging for a project to be built? The answer is that there is always an active configuration, which is the configuration that will be used when you ask Visual Studio to build a project. (Note that configurations are set for each project rather than for each solution.)

By default, when you create a project, the Debug configuration is the active configuration. You can change which configuration is the active one by clicking the Build menu option and selecting the Configuration Manager item. It is also available through a drop-down menu in the main Visual Studio toolbar.

Editing Configurations

In addition to choosing the active configuration, you can also examine and edit the configurations. To do this, you select the relevant project in the Solution Explorer and then select the Properties from the Project menu. This brings up a very sophisticated dialog box. (Alternatively, you can access the same dialog box by right-clicking the name of the project in the Solution Explorer and then selecting Properties from the context menu.)

This dialog contains a tree view, which allows you to select quite a lot of different general areas to examine or edit. We don’t have space to show all of these areas but we will show a couple of the most important ones.

Figure 14-23 shows a tabbed view of the available properties for a particular application. This screenshot shows the general application settings for the ConsoleApplication1 project that you created earlier in the chapter.

image from book
Figure 14-23

Among the points to note are that you can select the name of the assembly as well as the type of assembly to be generated. The options here are Console Application, Windows Application, and Class Library. You can, of course, change the assembly type if you want. (Though arguably, if you want, you might wonder why you didn’t pick the correct project type at the time that you asked Visual Studio to generate the project for you in the first place!)

Figure 14-24 shows the build configuration properties. You’ll notice that a list box near the top of the dialog box allows you to specify which configuration you want to look at. In this case you can see - in the case of the Debug configuration - that the compiler assumes that the DEBUG and TRACE preprocessor symbols have been defined. Also, the code is not optimized and extra debugging information is generated.

image from book
Figure 14-24

In general, it’s not that often that you’ll have to adjust the configuration settings. However, if you ever do need to use them, you now know the difference between the available configuration properties.

Debugging

After the long discussion about building and build configurations, you might be surprised to learn that this chapter is not going to spend a great deal of time discussing debugging itself. The reason for that is that the principles and the process of debugging - setting breakpoints and examining the values of variables - isn’t really significantly different in Visual Studio from in any of the various Visual Studio 6 IDEs. Instead, this section briefly reviews the features offered by Visual Studio, focusing on those areas that might be new to some developers. It also discusses how to deal with exceptions, because these can cause problems during debugging.

In C#, as in pre-.NET languages, the main technique involved in debugging is simply setting break-points and using them to examine what is going on in your code at a certain point in its execution.

Breakpoints

You can set breakpoints from Visual Studio on any line of your code that is actually executed. The simplest way is to click the line in the code editor, within the shaded area toward the far left of the document window (or press the F9 key when the appropriate line is selected). This sets up a breakpoint on that particular line, which causes execution to break and control to be transferred to the debugger as soon as that line is reached in the execution process. As in previous versions of Visual Studio, a breakpoint is indicated by a large circle to the left of the line in the code editor. Visual Studio also highlights the line by displaying the text and background in a different color. Clicking the circle again removes the breakpoint.

If breaking every time at a particular line isn’t adequate for your particular problem, you can also set conditional breakpoints. To do this, select Debug image from book Windows image from book Breakpoints. This brings up a dialog box asking you for details of the breakpoint you want to set. Among the options available, you can:

  • Specify that execution should break only after the breakpoint has been passed a certain number of times.

  • Specify that the breakpoint should come into effect only every so many times that the line is reached, for example every twentieth time that a line is executed. (This is useful when debugging large loops.)

  • Set the breakpoints relative to a variable rather than to an instruction. In this case, the value of the variable will be monitored and the breakpoints will be triggered whenever the value of this variable changes. You might find, however, that using this option slows down your code considerably. Checking whether the value of a variable has changed after every instruction adds a lot of processor time.

Watches

After a breakpoint has been hit you will usually want to investigate the values of variables. The simplest way to do this is to hover the mouse cursor over the name of the variable in the code editor. This causes a little box that shows the value of that variable to pop up, which can also be expanded to greater detail. This is shown in Figure 14-25.

image from book
Figure 14-25

However, you might also prefer to use the Autos window to examine the contents of variables. The Autos window (shown in Figure 14-26) is a tabbed window that appears only when the program is running under the debugger. If you don’t see it, try selecting Debug image from book Windows image from book Autos.

image from book
Figure 14-26

Variables that are classes or structs are shown with a + icon next to them, which you can click to expand the variable and see the values of its fields.

The three tabs to this window are each designed to monitor different variables:

  • Autos monitors the last few variables that have been accessed as the program was executing

  • Locals monitors variables that are accessible in the method currently being executed

  • Watch monitors any variables that you have explicitly specified by typing their names into the Watch window

Exceptions

Exceptions are great when you ship your application and for making sure that error conditions are handled in an appropriate way within your application. Used well, they can ensure that your application copes with difficulties well and that the user never gets presented with a technical dialog box. Unfortunately, exceptions are not so great when you’re trying to debug your application. The problem is twofold:

  • If an exception occurs when you’re debugging, you often don’t want it to be handled automatically - especially if automatically handling it means retiring gracefully and terminating execution! Rather, you want the debugger to help you find out why the exception has occurred. Of course the trouble is that if you have written good, robust, defensive code, your program will automatically handle almost anything - including the bugs that you want to detect!

  • If an exception occurs that you haven’t written a handler for, the .NET runtime will still go off looking for a handler. But by the time it discovers that there isn’t one, it will have terminated your program. There won’t be a call stack left and you won’t be able to look at the values of any of your variables, because they will all have gone out of scope.

Of course, you can set breakpoints in your catch blocks, but that often doesn’t help very much because when the catch block is reached, flow of execution will, by definition, have exited the corresponding try block. That means that the variables you probably wanted to examine the values of in order to find out what’s gone wrong will have gone out of scope. You won’t even be able to look at the stack trace to find out what method was being executed when the throw statement occurred - because control will have left that method. Setting the breakpoints at the throw statement will of course solve this, except that if you are coding defensively there will be a lot of throw statements in your code. How can you tell which one is the one that threw the exception?

In fact, Visual Studio provides a very neat answer to all of this. If you look into the main Debug menu, you’ll find a menu item called Exceptions. This item opens the Exceptions dialog box (see Figure 14-27), which allows you to specify what happens when an exception is thrown. You can choose to continue execution or to stop and start debugging - in which case execution stops and the debugger steps in at the throw statement itself.

image from book
Figure 14-27

What makes this a really powerful tool is that you can customize the behavior according to which class of exception is thrown. For example, in Figure 14-24, we’ve told Visual Studio to break into the debugger whenever it encounters any exception thrown by a .NET base class, but not to break into the debugger if the exception is an AppDomainUnloadedException.

Visual Studio knows about all the exception classes available in the .NET base classes, and also about quite a few exceptions that can be thrown outside the .NET environment. Visual Studio isn’t automatically aware of your own custom exception classes that you write, but you can manually add your exception classes to the list and thereby specify which of your exceptions should cause execution to stop immediately. To do this, just click the Add button (which is enabled when you have selected a top-level node from the tree) and type in the name of your exception class.




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net