You can reach the debug settings that apply to each of your solution's projects from the Solution Explorer window by right-clicking a project and choosing the Properties menu item.
You can find some build settings that affect your ability to debug a project on its Common Properties ’ Build property page, as shown in Figure 4-9.
On the Common Properties ’ Build page, you should ensure that Option Explicit is specified as "On" for every project in your solutions. When Option Explicit is switched on, you're forced to declare every variable that you use. This prevents you from mistyping the name of a variable in your code and thereby accidentally creating a new variable ”with Option Explicit On , any mistake like this is automatically flagged by the compiler as an error. Option Explicit On can also help you to avoid scoping mistakes. If you try to use a variable outside its scope, the compiler again flags this as an error instead of simply creating a new variable. This becomes especially important now that VB's block scoping rules have changed with the arrival of .NET, and you're able to have two variables with the same name within the same procedure.
On the same property page, you should always switch on Option Strict for every project in your solutions. Option Strict goes a step further than Option Explicit by adding automatic type-conversion checking to your applications. Without this setting, VB .NET allows the implicit conversion of one type to almost any other type, a "feature" that was often called Evil Type Coercion in VB.Classic. Examples of this behavior include data loss when converting a numeric variable to another variable of lesser size or precision, nonintuitive results when adding a numeric variable to a string variable that just happened to contain a number, and a runtime error when passing a string argument to a numeric procedure parameter.
With Option Strict On , the compiler always warns you when you perform an implicit type conversion that might result in data or precision loss. This is a good thing because it catches a whole genre of bugs automatically. You can, of course, still perform the type conversion explicitly, but you no longer have to worry about runtime errors based on accidental type conversions.
Because of the wide variety of possible projects that .NET allows you to create, Visual Studio gives you several different ways of starting a project so that you can debug it effectively. You can find the options that control the way a project starts on the Configuration Properties ’ Debugging property page, as shown in Figure 4-10.
On this page, you have the option to start the debugging of your project by using an external program or a URL. An example of when this is useful is for debugging a class library, otherwise known as a DLL. Because class libraries and certain other project types can't be run without being loaded by some other component, this page gives you the chance to specify that component. By default, it assumes that the starting component is already contained within your solution, so you can specify that component with the "Start project" option. Alternatively, you can specify some prebuilt component to start your debugging by using the "Start external program" option. If your project is invoked from a Web site, you can specify the URL by using the "Start URL" option. Finally, if your project is a Web application or a Web service, you are given the option to use the "Wait for an external process to connect" option. This causes the debugger to attach to any process that calls into your project, and any breakpoints that you've created in your project can then be triggered.
The Start Options section allows you to specify any command-line parameters that your project needs. You use the "Use remote machine" setting when you're debugging a program on a remote machine (for more about remote debugging and how to use this option, please see Chapter 15). If you don't select the "Always use Internet Explorer when debugging Web pages" option, Web pages will be loaded into the default Windows browser for debugging.
This page also allows you to choose the debuggers that you want to use ”the Debuggers section is relatively self-explanatory. Select the "Enable unmanaged code debugging" option if your project uses any COM or other native code components , and select the "Enable SQL Server debugging" option if your project makes any calls to SQL Server stored procedures. You can also set options that tell the debugger to attach to the Web server when debugging ASP .NET or old-style ASP Web projects. If you find that your project's breakpoints are not being triggered, the most likely reason is that you've forgotten to use this page to specify the type of projects that you're debugging.
When you're debugging a project, you should make sure that the project optimization options are set properly if you want to see reliable behavior in the Source window. You can find these settings on the Configuration Properties ’ Optimizations property page, shown in Figure 4-11.
On this page, you can specify the optimizations that you want the VB .NET language compiler to make when building your program. When building in debug mode, you should normally uncheck the "Remove integer overflow checks" and "Enable optimizations" options. Both of these options, if checked, ask the compiler to optimize the generated processor-native code as aggressively as possible. This can cause major problems for the debugger as it tries to work back from the optimized native code to the original source code. The effect of this is that the execution point displayed in the Source window during a debugging run can jump around erratically and be unreliable, which is why it's best to leave both of these options unchecked. For more information on the effects of these settings, please see the "Understanding Code Optimization" section later in this chapter.
You can find the final project properties that you need to consider on the Configuration Properties ’ Build page, as shown in Figure 4-12.
Regardless of the build configuration you're using, you should always, and I emphasize always , select the "Generate debugging information" option. This guarantees that the project's debug symbols (.pdb) file is built. Even with a fully optimized production release, you can debug the resulting assemblies provided you have the correct debug symbols available. You don't need to release the debug symbols to the end user , but you do need to have them available and under source control if you later want to do any debugging. Please see the "Debugging Production Applications" section later in the chapter for more details on how to do this effectively. A second benefit of having debug symbols is that any exception thrown by your application will include the exact line number where the exception was thrown. Without debug symbols, you usually have to resort to guessing which line of code actually caused the exception.
For a Debug build configuration, you should also select the DEBUG and TRACE conditional compilation constants to activate your debug and tracing code, such as statements that use the Debug and Trace classes.
You should also select the box marked "Treat compiler warnings as errors". Checking this option stops you from ignoring any compiler warnings. Some developers tend to ignore any compiler warnings on the basis that either the compiler is too dumb to understand what the developer is doing or the warning can be fixed at a later stage. Both of these assumptions are dangerous. If the compiler is giving a warning, you should heed it. Although your code may seem to work even with the warning, it's quite likely that you're storing up problems for the future, especially when your code encounters different conditions from those found during unit testing. Alternatively, if you say that you're going to fix the warning tomorrow, be aware that under severe project pressures "tomorrow" may never arrive . The next time you meet the problem that produced the warning may be in the form of a bug after your program has reached production.
You can look at this in another way: If you receive a warning letter from the Internal Revenue Service (IRS), is throwing the letter in the trashcan a good way of handling the situation? Sooner or later you have to pay, and in this case paying later is nearly always more expensive than paying now.