Section 2.1. Classes, Objects, and Types


2.1. Classes, Objects, and Types

The essence of object-oriented programming is the creation of new types. A type represents a thing. Sometimes the thing is abstract, such as a data table or a thread; sometimes it is more tangible, such as a button in a window. A type defines the thing's general properties and behaviors.

If your program uses three instances of a button type in a windowsay, an OK, a Cancel, and a Help buttoneach button will have a size, though the specific size of each button may differ. Similarly, all the buttons will have the same behaviors (draw, click), though how they actually implement these behaviors may vary. Thus, the details might differ among the individual buttons, but they are all of the same type.

As in many object-oriented programming languages, in C# a type is defined by a class, while the individual instances of that class are known as objects. Later chapters explain that there are other types in C# besides classes, including enums, structs, and delegates, but for now the focus is on classes.

The "Hello World" program declares a single type: the Hello class. To define a C# type, you declare it as a class using the class keyword, give it a namein this case, Helloand then define its properties and behaviors. The property and behavior definitions of a C# class must be enclosed by open and closed braces ({}).

C++ programmers take note: there is no semicolon after the closing brace.


2.1.1. Methods

A class has both properties and behaviors. Behaviors are defined with member methods; properties are discussed in Chapter 3.

A method is a function owned by your class. In fact, member methods are sometimes called member functions. The member methods define what your class can do or how it behaves. Typically, methods are given action names, such as WriteLine( ) or AddNumbers( ). In the case shown here, however, the class method has a special name, Main( ), which doesn't describe an action but does designate to the CLR that this is the main, or first method, for your class.

C++ programmers take note: Main( ) is capitalized in C# and must be a member of a class, not a global member. Main( ) can also return int or void.


The CLR calls Main() when your program starts. Main() is the entry point for your program, and every C# program must have a Main( ) method.[1]

[1] It's technically possible to have multiple Main( ) methods in C#; in that case you use the /main command-line switch to tell C# which class contains the Main( ) method that should serve as the entry point to the program.

Method declarations are a contract between the creator of the method and the consumer (user) of the method. It is likely that the creator and consumer of the method will be the same programmer, but this doesn't have to be so: it is possible that one member of a development team will create the method and another programmer will use it.

Java programmers take note: Main( ) is the entry point for every C# program, similar in some ways to the Java applet run( ) method or the Java program's main() method.


To declare a method, you specify a return value type followed by a name. Method declarations also require parentheses, whether the method accepts parameters or not. For example:

int myMethod(int size)

declares a method named myMethod() that takes one parameter: an integer that will be referred to within the method as size. This method returns an integer value. The return value type tells the consumer of the method what kind of data the method will return when it finishes running.

Some methods don't return a value at all; these are said to return void, which is specified by the void keyword. For example:

void myVoidMethod();

declares a method that returns void and takes no parameters. In C# you must always declare a return type or void.

2.1.2. Comments

A C# program can also contain comments. Take a look at the first line after the opening brace of the main method shown earlier:

// Use the system console object

The text begins with two forward slash marks (//). These designate a comment. A comment is a note to the programmer and doesn't affect how the program runs. C# supports three types of comments.

The first type, just shown, indicates that all text to the right of the comment mark is to be considered a comment, until the end of that line. This is known as a C++ style comment.

The second type of comment, known as a C-style comment, begins with an open comment mark (/*) and ends with a closed comment mark (*/). This allows comments to span more than one line without having to have // characters at the beginning of each comment line, as shown in Example 2-2.

Example 2-2. Illustrating multiline comments
namespace HelloWorld {     class HelloWorld     {         static void Main( )         {             /* Use the system console object                as explained in the text */             System.Console.WriteLine("Hello World");         }     } }

While you can't nest C++ style comments, it is possible to nest C++ style comments within C-style comments. For this reason, it is common to use C++ style comments whenever possible, and to reserve the C-style comments for "commenting-out" blocks of code.

The third and final type of comment that C# supports is used to associate external XML-based documentation with your code, and is illustrated in Chapter 13.

2.1.3. Console Applications

"Hello World" is an example of a console program. A console application typically has no graphical user interface (GUI); there are no list boxes, buttons, windows, and so forth. Text input and output are handled through the standard console (typically a command or DOS window on your PC). Sticking to console applications for now helps simplify the early examples in this book, and keeps the focus on the language itself. In later chapters, we'll turn our attention to Windows and web applications, and at that time we'll focus on the Visual Studio .NET GUI design tools.

All that the Main() method does in this simple example is write the text "Hello World" to the standard output (typically a command prompt window). Standard output is managed by an object named Console. This Console object has a method called WriteLine( ) that takes a string (a set of characters) and writes it to the standard output. When you run this program, a command or DOS screen will pop up on your computer monitor and display the words "Hello World."

You invoke a method with the dot operator (.). Thus, to call the Console object's WriteLine() method, you write Console.WriteLine(...), filling in the string to be printed.

2.1.4. Namespaces

Console is only one of a tremendous number of useful types that are part of the .NET FCL. Each class has a name, and thus the FCL contains thousands of names, such as ArrayList, Hashtable, FileDialog, DataException, EventArgs, and so on. There are hundreds, thousands, even tens of thousands of names.

This presents a problem. No developer can possibly memorize all the names that the .NET Framework uses, and sooner or later you are likely to create an object and give it a name that has already been used. What will happen if you purchase a Hashtable class from another vendor, only to discover that it conflicts with the Hashtable class that .NET provides? Remember, each class in C# must have a unique name and you typically can't rename classes in a vendor's code!

The solution to this problem is the use of namespaces. A namespace restricts a name's scope, making it meaningful only within the defined namespace.

C++ programmers take note: C++ namespaces are delimited with the scope resolution operator (::), in C# you use the dot (.) operator.


Java programmers take note: namespaces provide many of the benefits of packages.

Assume that I tell you that Jim is an engineer. The word "engineer" is used for many things in English, and can cause confusion. Does he design buildings? Write software? Run a train?

In English I might clarify by saying "he's a scientist," or "he's a train engineer." A C# programmer could tell you that Jim is a science.engineer rather than a TRain.engineer. The namespace (in this case, science or train) restricts the scope of the word that follows. It creates a "space" in which that name is meaningful.

Further, it might happen that Jim is not just any kind of science.engineer. Perhaps Jim graduated from MIT with a degree in software engineering, not civil engineering (are civil engineers especially polite?). Thus, the object that is Jim might be defined more specifically as a science.software.engineer. This classification implies that the namespace software is meaningful within the namespace science, and that engineer in this context is meaningful within the namespace software. If later you learn that Charlotte is a transportation.train.engineer, you will not be confused as to what kind of engineer she is. The two uses of engineer can coexist, each within its own namespace.

Similarly, if it turns out that .NET has a Hashtable class within its System.Collections namespace, and that I have also created a Hashtable class within a ProgCSharp.DataStructures namespace, there is no conflict because each exists in its own namespace.

In Example 2-1, the Console class' name is identified as being in the System namespace by using the code:

System.Console.WriteLine();

2.1.5. The Dot Operator (.)

In Example 2-1, the dot operator (.) is used both to access a method (and data) in a class (in this case, the method WriteLine( )), and to restrict the class name to a specific namespace (in this case, to locate Console within the System namespace). This works well because in both cases we are "drilling down" to find the exact thing we want. The top level is the System namespace (which contains all the System objects that the FCL provides); the Console type exists within that namespace, and the WriteLine() method is a member function of the Console type.

In many cases, namespaces are divided into subspaces. For example, the System namespace contains a number of subnamespaces such as Data, Configuration, Collections, and so forth, while the Collections namespace itself is divided into multiple subnamespaces.

Namespaces can help you organize and compartmentalize your types. When you write a complex C# program, you might want to create your own namespace hierarchy, and there is no limit to how deep this hierarchy can be. The goal of namespaces is to help you divide and conquer the complexity of your object hierarchy.

2.1.6. The using Keyword

Rather than writing the word System before Console, you could specify that you will be using types from the System namespace by writing the directive:

using System;

at the top of the listing, as shown in Example 2-3.

Example 2-3. The using keyword
using System; class Hello {     static void Main( )     {         //Console from the System namespace         Console.WriteLine("Hello World");     } }

Notice the using System directive is placed before the Hello class definition. Visual Studio .NET 2005 defaults to including three using statements in every console application (System, System.Collections.Generic, System.Text).

Although you can designate that you are using the System namespace, you can't designate that you are using the System.Console object, as you can with some languages. Example 2-4 won't compile.

Example 2-4. Code that doesn't compile (not legal C#)
using System.Console; class Hello {     static void Main( )     {         //Console from the System namespace         WriteLine("Hello World");     } }

This generates the compile error:

error CS0138: A using namespace directive can only be applied to namespaces; 'System.Console' is a type not a namespace

If you are using Visual Studio, you will know that you've made a mistake, because when you type usingSystem followed by the dot, Visual Studio .NET 2005 will provide a list of valid namespaces, and Console won't be among them.


The using keyword can save a great deal of typing, but it can undermine the advantages of namespaces by polluting the scope with many undifferentiated names. A common solution is to use the using keyword with the built-in namespaces and with your own corporate namespaces, but perhaps not with third-party components.

Some programming groups make it a policy to spell out the entire namespace path to the object (e.g., System.Console.WriteLine( ) and not Console.WriteLine()) as a form of documentation. This can become unworkable pretty quickly with deeply nested namespaces.


2.1.7. Case Sensitivity

C# is case-sensitive, which means that writeLine is not the same as WriteLine, which in turn is not the same as WRITELINE. Unfortunately, unlike in VB, the C# development environment will not fix your case mistakes; if you write the same word twice with different cases, you might introduce a tricky-to-find bug into your program.

A handy trick is to hover over a name that is correct in all but case and then hit Ctrl-Space. The Autocomplete feature of Intellisense will fix the case for you.


To prevent such a time-wasting and energy-depleting mistake, you should develop conventions for naming your variables, functions, constants, etc. The convention in this book is to name variables with camel notation (e.g., someVariableName), and to name functions, constants, and properties with Pascal notation (e.g., SomeFunction).

The only difference between camel and Pascal notation is that in Pascal notation, names begin with an uppercase letter.

Microsoft has developed code style guidelines that make a very good starting point (and often are all you need). You can download them from:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconNETFrameworkDesignGuidelines.asp


2.1.8. The static Keyword

The Main( ) method shown in Example 2-1 has one more designation. Just before the return type declaration void (which, you will remember, indicates that the method doesn't return a value) you'll find the keyword static:

static void Main()

The static keyword indicates that you can invoke Main( ) without first creating an object of type Hello. This somewhat complex issue will be considered in much greater detail in subsequent chapters. One of the problems with learning a new computer language is you must use some of the advanced features before you fully understand them. For now, you can treat the declaration of the Main( ) method as tantamount to magic.



Programming C#(c) Building. NET Applications with C#
Programming C#: Building .NET Applications with C#
ISBN: 0596006993
EAN: 2147483647
Year: 2003
Pages: 180
Authors: Jesse Liberty

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