Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro CSharp 2008 And The .NET 3.5 Platform [eng]

.pdf
Скачиваний:
71
Добавлен:
16.08.2013
Размер:
22.5 Mб
Скачать

62 CHAPTER 2 BUILDING C# APPLICATIONS

If you now look at the C# definition of the Car class, you will see it has been updated accordingly (minus the additional code comments):

public class Car

{

//Public data is typically a bad idea; however,

//it keeps this example simple.

public string PetName;

}

Drag another new Class onto the designer named SportsCar. Now, select the Inheritance icon from the Class Designer Toolbox and click the top of the SportsCar icon. Without releasing the left mouse button, move the mouse on top of the Car class icon and then release the mouse button.

If you performed these steps correctly, you have just derived the SportsCar class from Car (see Figure 2-29).

Figure 2-29. Visually deriving from an existing class

To complete this example, update the generated SportsCar class with a public method named GetPetName() authored as follows:

public class SportsCar : Car

{

public string GetPetName()

{

PetName = "Fred"; return PetName;

}

}

Object Test Bench

Another nice visual tool provided by Visual Studio 2008 is Object Test Bench (OTB). This aspect of the IDE allows you to quickly create an instance of a class and invoke its members without running the entire application. This can be extremely helpful when you wish to test a specific method, but

CHAPTER 2 BUILDING C# APPLICATIONS

63

would rather not step through dozens of lines of code to do so. It is also very useful when you are building a .NET code library, and would rather not create a client application to test its functionality.

Note One limitation of the OTB is that it has no ability to handle incoming events sent from a given object. If you need to test the incoming events, you will be required to build a separate assembly to do so.

To work with OTB, right-click the type you wish to create using the Class Designer. For example, right-click the SportsCar type, and from the resulting context menu select Create Instance SportsCar(). This will display a dialog box that allows you to name your temporary object variable (and supply any constructor arguments if required). Once the process is complete, you will find your object hosted within the IDE. Right-click the object icon and invoke the GetPetName() method (see Figure 2-30).

Figure 2-30. The Visual Studio 2008 Object Test Bench

Once you do, you will see the value Fred displayed in the Method Call Result dialog box. In fact, if you wish, you can save this value as a new object (of type System.String) on the OTB.

The Integrated .NET Framework 3.5 Documentation System

The final aspect of Visual Studio 2008 you must be comfortable with from the outset is the fully integrated help system. The .NET Framework 3.5 SDK documentation is extremely good, very readable, and full of useful information. Given the huge number of predefined .NET types (which number well into the thousands), you must be willing to roll up your sleeves and dig into the provided documentation. If you resist, you are doomed to a long, frustrating, and painful existence as a .NET developer.

Visual Studio 2008 provides the Dynamic Help window (accessible from the Help menu), which changes its contents based on what item (window, menu, source code keyword, etc.) is currently selected. For example, if you place the cursor on the Console class, the Dynamic Help window displays a set of links regarding the System.Console type.

Note Another great shortcut is to click once (but don’t select) a C# keyword or .NET type and press the F1 key. This will automatically open the documentation for the item containing the blinking text cursor.

You should also be aware of a very important subdirectory of the .NET Framework 3.5 SDK documentation. Under the .NET Development .NET Framework SDK .NET Framework

.NET Framework Class Library Reference node of the documentation, you will find complete documentation of each and every namespace in the .NET base class libraries (see Figure 2-31).

64 CHAPTER 2 BUILDING C# APPLICATIONS

Figure 2-31. The .NET base class library reference

Each node in the tree defines the set of types in a given namespace, the members of a given type, and the parameters of a given member. Furthermore, when you view the help page for a given type, you will be told the name of the assembly and namespace that contains the type in question (located at the top of said page). As you read through the remainder of this book, I assume that you will dive into this very, very critical node to read up on additional details of the entity under examination.

Note At the risk of sounding like a broken record, I really can’t emphasize enough how important it is that you learn to use the .NET Framework 3.5 SDK documentation. No book, no matter how lengthy, can cover every aspect of the .NET platform. Make sure you take some time to get comfortable using the help system; you’ll thank yourself later.

A Partial Catalog of Additional .NET

Development Tools

To conclude this chapter, I would like to point out a number of .NET development tools that complement the functionality provided by your IDE of choice. Many of the tools mentioned here are open source, and all of them are free of charge. While I don’t have the space to cover the details of these utilities, Table 2-3 lists a number of the tools I have found to be extremely helpful as well as URLs you can visit to find more information about them.

 

CHAPTER 2 BUILDING C# APPLICATIONS

65

Table 2-3. Select .NET Development Tools

 

 

 

 

 

 

 

 

Tool

Meaning in Life

URL

 

FxCop

This is a must-have for any .NET developer

http://www.gotdotnet.

 

 

interested in .NET best practices. FxCop

com/team/fxcop

 

 

will test any .NET assembly against the

 

 

 

 

official Microsoft .NET best-practice

 

 

 

 

coding guidelines.

 

 

 

Lutz Roeder’s Reflector

This advanced .NET decompiler/object

http://www.aisto.com/

 

 

browser allows you to view the .NET

roeder/dotnet

 

 

implementation of any .NET type using

 

 

 

 

a variety of languages.

 

 

 

NAnt

NAnt is the .NET equivalent of Ant, the

http://sourceforge.

 

 

popular Java automated build tool. NAnt

net/projects/nant

 

 

allows you to define and execute detailed

 

 

 

 

build scripts using an XML-based syntax.

 

 

 

NDoc

NDoc is a tool that will generate code

http://sourceforge.

 

 

documentation files for C# code (or a

net/projects/ndoc

 

 

compiled .NET assembly) in a variety

 

 

 

 

of popular formats (MSDN’s *.chm, XML,

 

 

 

 

HTML, Javadoc, and LaTeX).

 

 

 

NUnit

NUnit is the .NET equivalent of the

http://www.nunit.org

 

 

Java-centric JUnit unit testing tool. Using

 

 

 

 

NUnit, you are able to facilitate the testing

 

 

 

 

of your managed code.

 

 

 

 

 

 

 

 

Summary

So as you can see, you have many new toys at your disposal! The point of this chapter was to provide you with a tour of the major programming tools a C# programmer may leverage during the development process. You began the journey by learning how to generate .NET assemblies using nothing other than the free C# compiler and Notepad. Next, you were introduced to the TextPad and Notepad++ applications and walked through the process of using these tools to edit and compile *.cs code files.

You also examined three feature-rich IDEs, starting with the open source SharpDevelop, followed by Microsoft’s Visual C# 2008 Express and Visual Studio 2008 Professional. While this chapter only scratched the surface of each tool’s functionality, you should be in a good position to explore your chosen IDE at your leisure (and recall, you’ll see additional features of Visual Studio 2008 as you progress through the book). The chapter wrapped up by examining various open source .NET development tools that extend the functionality of your IDE of choice.

P A R T 2

Core C# Programming

Constructs

C H A P T E R 3

Core C# Programming Constructs,

Part I

This chapter begins your formal investigation of the C# programming language by presenting a number of bite-sized, stand-alone topics you must be comfortable with as you explore the .NET Framework. The first order of business is to understand how to build your program’s application object and the composition of an executable program’s entry point: the Main() method. Next, you will investigate the intrinsic C# data types (and their equivalent types in the System namespace) including an examination of the System.String and System.Text.StringBuilder class types.

Once you know the details of the fundamental .NET data types, you will then examine a number of data type conversion techniques, including narrowing operations, widening operations, and the use of the unchecked keyword. We wrap up this chapter by examining the core operators, iteration constructs, and decision constructs used to build valid C# code statements.

The Anatomy of a Simple C# Program

C# demands that all program logic be contained within a type definition (recall from Chapter 1 that type is a general term referring to a member of the set {class, interface, structure, enumeration, delegate}). Unlike many other languages, in C# it is not possible to create global functions or global points of data. Rather, all data members and methods must be contained within a type definition. To get the ball rolling, create a new Console Application project named SimpleCSharpApp. As you might agree, the initial code statements are rather uneventful:

using System;

using System.Collections.Generic; using System.Text;

using System.Linq;

namespace SimpleCSharpApp

{

class Program

{

static void Main(string[] args)

{

}

}

}

69

70CHAPTER 3 CORE C# PROGRAMMING CONSTRUCTS, PART I

Given this, update the Main() method with the following code statements:

class Program

{

static void Main(string[] args)

{

//Display a simple message to the user.

Console.WriteLine("***** My First C# App *****");

Console.WriteLine("Hello World!"); Console.WriteLine();

//Wait for Enter key to be pressed before shutting down.

Console.ReadLine();

}

}

Here, we have a definition for a class type that supports a single method named Main(). By default, Visual Studio 2008 names the class defining Main() “Program”; however, you are free to change this if you so choose. Every executable C# application (console program, Windows desktop program, or Windows service) must contain a class defining a Main() method, which is used to signify the entry point of the application.

Formally speaking, the class that defines the Main() method is termed the application object. While it is possible for a single executable application to have more than one application object (which can be useful when performing unit tests), you must inform the compiler which Main() method should be used as the entry point via the /main option of the command-line compiler.

Note that the signature of Main() is adorned with the static keyword, which will be examined in detail in Chapter 5. For the time being, simply understand that static members are scoped to the class level (rather than the object level) and can thus be invoked without the need to first create a new class instance.

Note C# is a case-sensitive programming language. Therefore, “Main” is not the same as “main,” and “Readline” is not the same as “ReadLine.” Given this, be aware that all C# keywords are lowercase (public, lock, class, global, and so on), while namespaces, types, and member names begin (by convention) with an initial capital letter and have capitalized the first letter of any embedded words (e.g., Console.WriteLine,

System.Windows.Forms.MessageBox, System.Data.SqlClient, and so on). As a rule of thumb, whenever you receive a compiler error regarding “undefined symbols,” be sure to check your spelling!

In addition to the static keyword, this Main() method has a single parameter, which happens to be an array of strings (string[] args). Although you are not currently bothering to process this array, this parameter may contain any number of incoming command-line arguments (you’ll see how to access them momentarily). Finally, this Main() method has been set up with a void return value, meaning we do not explicitly define a return value using the return keyword before exiting the method scope.

The logic of Program is within Main() itself. Here, you make use of the Console class, which is defined within the System namespace. Among its set of members is the static WriteLine() which, as you might assume, pumps a text string and carriage return to the standard output. You also make a call to Console.ReadLine() to ensure the command prompt launched by the Visual Studio 2008 IDE remains visible during a debugging session until you press the Enter key.

CHAPTER 3 CORE C# PROGRAMMING CONSTRUCTS, PART I

71

Variations on the Main() Method

By default, Visual Studio 2008 will generate a Main() method that has a void return value and an array of string types as the single input parameter. This is not the only possible form of Main(), however. It is permissible to construct your application’s entry point using any of the following signatures (assuming it is contained within a C# class or structure definition):

//int return type, array of strings as the argument. static int Main(string[] args)

{

}

//No return type, no arguments.

static void Main()

{

}

// int return type, no arguments. static int Main()

{

}

Note The Main() method may also be defined as public as opposed to private, which is assumed if you do not supply a specific access modifier. Visual Studio 2008 automatically defines a program’s Main() method as implicitly private. Doing so ensures other applications cannot directly invoke the entry point of another.

Obviously, your choice of how to construct Main() will be based on two questions. First, do you want to return a value to the system when Main() has completed and your program terminates? If so, you need to return an int data type rather than void. Second, do you need to process any usersupplied command-line parameters? If so, they will be stored in the array of strings. Let’s examine all of our options.

Specifying an Application Error Code

While a vast majority of your Main() methods will return void as the return value, the ability to return an int from Main() keeps C# consistent with other C-based languages. By convention, returning the value 0 indicates the program has terminated successfully, while another value (such as -1) represents an error condition (do be aware that the value 0 is automatically returned, even if you construct a Main() method prototyped to return void).

On the Windows operating system, an application’s return value is stored within a system environment variable named %ERRORLEVEL%. If you were to create an application that programmatically launches another executable (a topic examined in Chapter 17), you can obtain the value of

%ERRORLEVEL% using the static System.Diagnostics.Process.ExitCode property.

Given that an application’s return value is passed to the system at the time the application terminates, it is obviously not possible for an application to obtain and display its final error code while running. However, to illustrate how to view this error level upon program termination, begin by updating the Main() method as follows:

// Note we are now returning an int, rather than void. static int Main(string[] args)

{

// Display a message and wait for Enter key to be pressed.