developmentor - a developer services company				  
				      C# Tutorial
   Modules

Class


Goals:

  • Introduce the concept of class.
  • Describe how to define fields and methods.
  • Show how to create and manipulate objects.
  • Examine the most common parameter passing options.

Overview

C# code is primarily organized into classes. A class contains both the data and operations needed to implement a type. For example, if a drawing program needed the concept of 'rectangle' then all the code needed to implement the rectangle type would be collected into a Rectangle class. Grouping code in this way is not only clean and organized, it also makes it easy to locate the appropriate code for maintenance, extension, or debugging.


Class

A class represents a concept in the application domain. Programmers working on a graphics program might have classes such as Circle, Rectangle, and Line. A team working on a financial application would have classes such as Stock, Bond, and Property. In C#, a class is the primary way to create a user defined data type.

A class is defined using the keyword class, the name of the class, and the body of the class enclosed in curly braces.


Fields

A class can contain fields to store data. Fields are defined using the type name and the field name. Fields defined in this way are called "instance fields" or "instance variables" since each instance of the class gets it own copy. Note that fields are defined at class scope; that is, they are not defined inside a method.


Object creation

Objects of class type are created using the new operator. new allocates memory for all the instance fields of the class.


Member access

The dot operator is used to access class members. Instance members must be accessed using an object so the syntax is typically object.member.


Methods

The operations supported by a class are defined using methods. For example, a rectangle type might support operations such as Draw, Move, Area, etc. while a stock type would offer Buy, Sell, SetPrice, etc. In C#, methods must be placed inside a class. A method is defined by specifying the return type, name, parameter list, and body. A return type of void is used for methods that do not return a value. Methods defined in this way are called "instance methods" since they must be invoked on an object of the class.

The set of methods offered by a stock class might look something like the following.

Methods are invoked by applying the dot operator to an object, selecting the desired method by name, and enclosing the arguments in parentheses.

Methods typically need access to the fields of the class. For example, the rectangle Area method must access the width and height of the rectangle, and the stock Buy method needs to modify the number of shares owned. To understand how methods are able to access needed fields it helps to examine the concept of the "current object". Suppose there two stock objects in existence: ibm and sun as shown below.

Each time an instance method is invoked, a particular object must be specified. For example, a method call such as ibm.Buy(...) would manipulate the ibm object whils sun.Sell(...) would access sun. Thus in each method call there is the concept of the "current object"; that is, the object on which the method was invoked. The notion of the current object is formalized by the keyword this. When a method is invoked, the runtime arranges for this to represent the object on which the method was called. this exists only for the duration of the method call and is only accessible from inside the method.

Method implementations use this as a handle to get access to the members of the current object.

In the previous example, the method parameter and a field were both named shares. Because of the ambiguity, use of this was required in order to access the field. If this were omitted, the code would have compiled; however, both uses of the name shares would have referred to the parameter and the field would not have been updated. In situations where there is no ambiguity, this can be safely omitted and the correct class member will still be accessed.

Methods may return a value. To return a value, the method declaration must specify the type of data returned and the method implementation must use the keyword return to send the data out of the method. For example, the stock class might supply a method such as Value which computes and returns the current value of the stock.

The entire implementation of the stock class is shown below for reference.


Method overloading

It is legal for a class to offer more than one method with the same name as long as the parameter lists are different. For example, the stock class could offer multiple versions of the Buy method that perform slightly different operations. The compiler examines the client code and calls the correct version based on the type and amount of data passed.


Parameter passing

There are three primary ways to pass parameters to methods: value, ref, or out.

A value parameter can be thought of as "in only"; that is, the data passed is copied into the method and the method then operates on the local copy. Any changes made by the method modify only the local copy and are lost when the method ends. Pass by value is the default parameter passing mechanism so there is no keyword needed to specify its use.

An out parameter is "out only"; that is, no data is passed into the method but an assignment to the parameter is visible in the client code. The keyword out must be placed on both the method definition and the method call to create an out parameter.

A ref parameter is "in and out"; that is, the parameter is just a "handle" or "reference" to the actual argument. The value is available for reading and/or writing and any changes made inside the method are visible in the outside world. The keyword ref must be placed on both the method definition and the method call to create a ref parameter.


Member access

C# provides the ability to control access to class members. The three most common access levels are public, private, and protected. We will cover public and private here and discuss protected later during the module on inheritance.

The class designer can choose to limit the usage of a field or method by adding the keyword private to its declaration. private members can only be accessed from inside that class. Consider the following implementation of a stock class where the fields have been made private. Note how the methods inside the stock class are able to access the private fields while the client code outside the stock class cannot.

Private is the default access level, so the following two declarations are equivalent.

To allow client code to access a field or method, the member can be made public by adding the keyword public to its declaration.

The public/private split allows a class to be divided into interface and implementation. The implementation is kept private while the interface is made public. Client code can only access the public interface and is prevented from directly accessing the implementation. This concept is often described using the terms 'encapsulation' and 'information hiding'. The most commonly cited advantage of this coding style is that the class designer is free to modify the implementation at any time without breaking any client code. This is possible since the client code cannot access the implementation directly anyway so changes have no impact.


Naming conventions

Some naming conventions have been adopted by C# developers in order to increase the uniformity of code written by different programmers in different organizations. Most names use the "intercaps" convention where the first letter of each word is capitalized.

Class names are intercaps with an initial capital letter.

Method names are intercaps with an initial capital letter.

Method parameters are intercaps with an initial lower case letter.

Public fields are intercaps with an initial capital letter.

Private fields are intercaps with an initial lower case letter.

This material is excerpted from the Programming C# course offered by DevelopMentor.