Home

Introduction to Classes

 

A Re-Introduction to Classes

 

Overview

Based on a brief definition we had in the first lesson, we have been using classes in a very introductory manner. This was necessary because everything in C# is built around a concept of class. A class can be more elaborate than what we have been acquainted to. A class is a technique of creating one or a group of variables to be used as a foundation for a more detailed variable. A class must be created in a computer file. You can create such a file with only one class or you can create many classes inside of one file.

To create a class, you start with the class keyword followed by a name and its body delimited by curly brackets. Here is an example of a class called Book:

class Book
{
}

HomePractical Learning: Introducing Classes

  1. Start Notepad
  2. In the empty file, type the following:
     
    using System;
    
    class DepartmentStore
    {
    }
    
    class Exercise
    {
        static void Main()
        {
        }
    }
  3. Save the file in a new folder named DeptStore1
  4. Save the file itself as Exercise.cs in the DeptStore1 folder

Class Variable Declaration

Like any normal variable, to use a class in your program, you can first declare a variable for it (when we study static fields, we will see that you can use a class without primarily declaring it). Like the variables we introduced in the previous lesson, to declare a variable of a class, type its name followed by a name for the variable. For example, to declare a variable of the above Book in another class called NewProject, you could type the following:

using System;

class Book
{
}

class NewProject
{

	static void Main()
	{
		Book ToRead;
	}
}

The variables we have declared so far are called value variables. This is because such a variable of a primitive type holds its value. The C# language supports another type of variable. This time, when you declare the variable, its name doesn't hold the value of the variable; it holds a reference to the address where the actual variable is stored. This reference type is the kind used to declare a variable for a class.

To use a variable as reference, you must initialize it using an operator called new. Here is an example:

using System;

class Book
{
}

class NewProject
{

	static void Main()
	{
		Book ToRead;
		
		ToRead = new Book();
	}
}

You can also use the new operator directly when declaring the variable as follows:

Book ToRead = new Book();

In C#, as well as Visual Basic, if you create a class in any of the files that belong to the same project, the class is made available to all other parts of the same project.

 

Practical LearningPractical Learning: Declaring a Class Variable

  1. To use the DepartmentStore class in the main class of the project, declare the variable as follows:
     
    using System;
    
    class DepartmentStore
    {
    }
    
    class Exercise
    {
        static void Main()
        {
    	DepartmentStore dptStore = new DepartmentStore();
        }
    }
  2. Save the exercise.cs file

Sharing Classes

Unlike its sisters the C and the C++ languages, C# was developed with the idea of working complementarily with other languages such as C++, Visual Basic, and J#. In other words, code from these other languages should be able to "read" or access code written in a C# application. To make this possible, a C# class can be created as a public object.

If you want your class to be accessible to code written in other languages, precede the class keyword with public when creating it. Here is an example:

using System;

public class Exercise
{
	static void Main()
	{
		int Number = 244;
		object Thing  = 1450.58;

		Console.WriteLine(Number);
		Console.WriteLine(Thing);
	}
}

Garbage Collection

When you initialize a variable using the new operator, you are in fact asking the compiler to provide you some memory space in the heap memory. The compiler is said to "allocate" memory for your variable. When that variable is no longer needed, such as when your program closes, it (the variable) must be removed from memory and the space it was using can be made available to other variables or other programs. This is referred to as garbage collection. In the past, namely in C/C++, this was a concern for programmers because they usually had to remember to manually delete such a variable (a pointer) and free its memory.

The .NET Framework solves the problem of garbage collection by letting the compiler "clean" memory after you. This is done automatically when the compiler judges it necessary so that the programmer doesn't need to worry about this issue.

A Program With Various Files

Instead of only one file, you can create a program with many of them. Each file can contain different assignments that, when put together, can create an application as complete as possible. To make this possible, you can create each file with a name and the extension .cs. To compile the project, after typing csc, you can list the files separated by commas.

Author Note In C++ and Pascal, if you create a class CA in a certain file FA and want to access anything included in that class from another file FB, you must type #include (C/C++) or uses (Pascal) followed by the name of the file FA somewhere in the top section of the file FB.
 

Class' Fields

 

Introduction

Consider the Book class defined earlier:

public class Book
{
}

The section between the curly brackets of a class is referred to as its body. In the body of a class, you can create a list of the parts that make up the class. Each of these parts must be a complete variable with a name and a data type. For example, here are the characteristics that make up a book, declared as the parts of the above Book class and each declared as a variable:

public class Book
{
	string Title;
	string Author;
	short  YearPublished;
	int    NumberOfPages;
	char   CoverType;
}

The variables declared in the body of a class are referred to as its member variables and each member variable is referred to as a field. The fields can be any type we have seen in the previous lesson. Based on this, when creating a class, it is your job to decide what your object is made of.

 
 

HomePractical Learning: Introducing Class Members

Imagine you want to write a (console-based) program for a department store and the customer has given you a preliminary catalog as follows:

Stock #: 437876
Women Spring Coat Classy
Unit: $145.55
Stock #: 79475
Women Bathing Suit Sandstone
$75.55
Stock #: 74797
Women Suit Exchange
$225.75
Stock: 68432
Men Jacket
$115.85
Stock #: 75947
Children Summer Hat
$17.95
Stock #: 48746
Children Playground Dress
$24.55

Each item in this catalog is represented by its Stock number, its name or description, and its price. Based on this, you can create a class that represents each item.

  1. Change the DepartmentStore class as follows:
     
    using System;
    
    public class DepartmentStore
    {
        long   ItemNumber;
        string ItemName;
        double UnitPrice;
    }
    
    public class Exercise
    {
        static void Main()
        {
    	DepartmentStore dptStore = new DepartmentStore();
        }
    }
  2. Save the file
 

Access to Class Members

The parts of an object fall into two main categories: those you can touch and those you don't have access to. For example, for a car parked at the mall, you can see or touch its doors and its tires but you don't see its engine or its spare tire, you don't even know if it has one. The parts of an object that you have access to are referred to as public. Those you can't see or touch are referred to as private.

A C# class also recognizes that some parts of a class can be made available to other classes and some other parts can be hidden from other classes. A part that must be hidden from other classes is private and it can be declared starting with the private keyword. If you declare a member variable and want to make it available to other classes, you must start its name with the public keyword. The public and private keywords are referred to as access level.

By default, if you declare a member variable (or anything else) in a class but don't specify its access level, the member is considered private and cannot be accessed from outside, that is by a non-member, of that class. Therefore, to make a member accessible by other classes, you must declare it as public.

You can use a mix of public and private members in a class and there is no rule on which access level should be listed first or last. Here is an example:

public class Book
{
	public string Title;
	public string Author";
	short  YearPublished;
	private int    NumberOfPages;
	char   CoverType;
}

Just keep in mind that if you omit or forget the access level of a member of a class, the member is automatically made private.

After declaring a member of a class, to access it from another class, first declare a variable from its class as we saw earlier. To actually access the method, use the period operator as follows:

using System;

class Book
{
	public string Title;
	public string Author;
	short  YearPublished;
	private int    NumberOfPages;
	char   CoverType;
}

class BookClub
{
	static void Main()
	{
		Book ToRead = new Book();
		ToRead.Author = "Francis Patrick Kouma";

		Console.WriteLine(ToRead.Author);
	}
}

To reduce confusion as to what member is public or private, we will always specify the access level of a member variable.

 

Practical Learning Practical Learning: Using a Class' Fields

  1. To make public the members of the DepartmentStore class, type the public keyword to their left
  2. To access the members of the DepartmentStore class, change Main() as follows:
     
    using System;
    
    public class DepartmentStore
    {
    	public long   ItemNumber;
    	public string ItemName;
    	public double UnitPrice;
    }
    
    public class Exercise
    {
    	static void Main()
    	{
    		DepartmentStore dptStore = new DepartmentStore();
    
    		dptStore.ItemNumber = 846785;
    		dptStore.ItemName   = "Women Underwear";
    		dptStore.UnitPrice  = 15.65;
    
    		Console.WriteLine("Department Store");
    		Console.WriteLine("Item #:      {0}",   dptStore.ItemNumber);
    		Console.WriteLine("Description: {0}",   dptStore.ItemName);
    		Console.WriteLine("Unit Price:  {0:C}\n", dptStore.UnitPrice);
    	}
    }
  3. Save the Exercise.cs file
  4. Open the Command Prompt and switch to the DeptStore1 folder that contains the current exercise
  5. To compile the project, type csc Exercise.cs
  6. To execute the application, type exercise and press Enter. This would produce:
     
  7. Return to Notepad
 

Characteristics of Members of a Class

 

Constants

Unlike C/C++, in C#, you can create a constant variable in a class. As done in Lesson 2 when studying variables, to declare a constant variable, type the const keyword to the left of the variable. Once again, when declaring a constant, you must initialize it with an appropriate constant value. Here is an example:

using System;

public class Exercise
{
	public static void MeterToInch()
	{
		const double ConversionFactor = 39.37;
		double Meter, Inch;
		string Answer;

		do 
		{
			Console.Write("Enter the value in meters:   ");
			Meter = double.Parse(Console.ReadLine());
			
			Inch = Meter * ConversionFactor;
			Console.WriteLine("{0}m = {1}in", Meter, Inch);

			Console.Write("\nDo you want to perform another conversions(y/n)? ");
			Answer = Console.ReadLine();
			Console.WriteLine();
		} while(Answer == "y" || Answer == "Y");
	}

	static void Main()
	{
		MeterToInch();
	}
}

Here is an example of running the program:

Enter the value in meters: 25.38
25.38m = 999.2106in

Do you want to perform another conversions(y/n)? y

Enter the value in meters: 44.68
44.68m = 1759.0516in

Do you want to perform another conversions(y/n)? Y

Enter the value in meters: 18.28
18.28m = 719.6836in

Do you want to perform another conversions(y/n)? n
 

Practical Learning Practical Learning: Creating a Constant

  1. To start a new file, on the main menu of Notepad, click File -> New
  2. In addition to what we have learned so far, to create two constants, type the following:
     
    using System;
    
    class IceCream
    {
    	public const decimal BasePrice     = 1.05M;
    	public const string  DefaultFlavor = "Diet Mint Fudge High Carb";
    	
    	public char Flavor;
    	public char Container;
    	public char Ingredient;
    	public int Scoops;
    	public decimal TotalPrice;
    }
    
    class Exercise
    {
    	static void Main()
    	{
    	}
    }
  3. Save the file in a new folder named IceCream1
  4. Save the file itself as Exercise.cs
  5. At the Command Prompt, switch to the IceCream1 directory
  6. Compile and test the file then return to Notepad
 

Read-Only Fields

When creating a member variable of a class, one of the decisions you make consists of deciding how the field would get its value(s). Sometimes you will allow the clients of the class to change the values of the field. In some other cases, you may want the field to only hold or present the value without being able to change it. This can still allow the clients to access the field and its value but on a read-only basis.

To create a field whose value can only be read, precede its data type, during declaration, with the readonly keyword. Here is an example:

public readonly double PI;

After declaring the variable, you should initialize it. You have two main alternatives. You can initialize the field when declaring it. Here is an example:

using System;

namespace Geometry
{
	class Circle
	{
		public double Radius;

		public Circle(double rad)
		{
			Radius = rad;
		}

		public readonly double PI = 3.14159;
	}

	class Exercise
	{
		static int Main()
		{
			Circle circ = new Circle(24.72);

			Console.WriteLine("Circle Characteristics");
			Console.WriteLine("Radius: {0}", circ.Radius);
			Console.WriteLine("PI:     {0}\n", circ.PI);

			return 0;
		}
	}
}

Alternatively, you can initialize the field in the(a) constructor of its class. This would be done as follows:

using System;

namespace Geometry
{
	class Circle
	{
		public double Radius;

		public Circle(double rad)
		{
			Radius = rad;
			PI = 3.14159;
		}

		public readonly double PI;
	}

	class Exercise
	{
		static int Main()
		{
			Circle circ = new Circle(24.72);

			Console.WriteLine("Circle Characteristics");
			Console.WriteLine("Radius: {0}", circ.Radius);
			Console.WriteLine("PI:     {0}\n", circ.PI);

			return 0;
		}
	}
}

If the value held by a read-only field is gotten from an expression, then the field must be initialized in the(a) construction with the desired expression. Based on this, the following code will not compile:

using System;

namespace Geometry
{
	class Circle
	{
		public double Radius;

		public Circle(double rad)
		{
			Radius = rad;
			PI = 3.14159;
		}

		public readonly double PI;
		public readonly double Diameter = Radius * 2;
	}

	class Exercise
	{
		static int Main()
		{
			Circle circ = new Circle(24.72);

			Console.WriteLine("Circle Characteristics");
			Console.WriteLine("Radius:   {0}", circ.Radius);
			Console.WriteLine("PI:       {0}\n", circ.PI);
			Console.WriteLine("Diameter: {0}\n", circ.Diameter);

			return 0;
		}
	}
}

This would produce:

C:\Programs\MSVCS\Project1\Exercise.cs(16): A field initializer cannot reference the nonstatic field, method, or property 'Geometry.Circle.Radius'

One solution to this error is to declare the field as read-only in the class and then initialize it in the(a) constructor with the expression. Here are a few examples:

using System;

namespace Geometry
{
	class Circle
	{
		public double Radius;

		public Circle(double rad)
		{
			Radius   = rad;
			Diameter = Radius * 2;
			Circumference = Diameter * PI;
			Area = Radius * Radius * PI;
		}

		public readonly double PI = 3.14159;
		public readonly double Diameter;
		public readonly double Circumference;
		public readonly double Area;
	}

	class Exercise
	{
		static int Main()
		{
			Circle circ = new Circle(24.72);

			Console.WriteLine("Circle Characteristics");
			Console.WriteLine("Radius:        {0}", circ.Radius);
			Console.WriteLine("Diameter:      {0}", circ.Diameter);
			Console.WriteLine("Circumference: {0}", circ.Circumference);
			Console.WriteLine("Area:          {0}\n", circ.Area);

			return 0;
		}
	}
}

This would produce:

Circle Characteristics
Radius:        24.72
Diameter:      49.44
Circumference: 155.3202096
Area:          1919.757790656

In the previous section, we saw that a constant variable must be initialized when it is created. Although a read-only variable seems to follow the same rule, it doesn't. Remember that you don't need to initialize a read-only variable when you declare it since you can do this in the(a) constructor of the class. Also, because a constructor can be overloaded, a read-only field can hold different values depending on the particular constructor that is accessed at a particular time but the value of a constant variable cannot change: it is initialized once, in the class (or in a method) and it keeps that value throughout the class (or method).

 

Static Fields

Imagine you create a class called Book. To access it in the Main() function, you can declare its variable, as we have done so far. A variable you have declared of a class is also called an instance of the class. In the same way, you can declare various instances of the same class as necessary:

using System;

public class Book
{
	public string Title;
	public string Author";
	public short  YearPublished;
	public int      NumberOfPages;
	public char   CoverType;
}

public class NewProject
{
	static void Main()
	{
		Book written = new Book();
		Book bought  = new Book();
	}
}

Each one of these instances gives you access to the members of the class but each instance holds the particular values of the members of its instance. Consider the results of the following program:

using System;

public class Book
{
    public string Title;
    public string Author;
    public short  YearPublished;
    public int    NumberOfPages;
    public char   CoverType;
}

public class Program
{
        static void Main()
        {
            Book First = new Book();

            First.Title         = "Psychology and Human Evolution";
            First.Author        = "Jeannot Lamm";
            First.YearPublished = 1996;
            First.NumberOfPages = 872;
            First.CoverType     = 'H';

            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:  {0}", First.Title);
            Console.WriteLine("Author: {0}", First.Author);
            Console.WriteLine("Year:   {0}", First.YearPublished);
            Console.WriteLine("Pages:  {0}", First.NumberOfPages);
            Console.WriteLine("Cover:  {0}\n", First.CoverType);

            Book Second = new Book();

            Second.Title = "C# First Step";
            Second.Author = "Alexandra Nyango";
            Second.YearPublished = 2004;
            Second.NumberOfPages = 604;
            Second.CoverType = 'P';

            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:     {0}", Second.Title);
            Console.WriteLine("Author: {0}", Second.Author);
            Console.WriteLine("Year:    {0}", Second.YearPublished);
            Console.WriteLine("Pages: {0}", Second.NumberOfPages);
            Console.WriteLine("Cover:  {0}\n", Second.CoverType);
        }
}

This would produce:

Book Characteristics
Title:  Psychology and Human Evolution
Author: Jeannot Lamm
Year:   1996
Pages:  872
Cover:  H

Book Characteristics
Title:  C# First Step
Author: Alexandra Nyango
Year:   2004
Pages:  604
Cover:  P

All of the member variables and methods of classes we have used so far are referred to as instance members because, in order to access them, you must have an instance of a class declared in another class in which you want to access them.

C# allows you to declare a class member and refer to it regardless of which instance of an object you are using. Such a member variable is called static. To declare a member variable of a class as static, type the static keyword on its left. Whenever you have a static member, in order to refer to it, you must "qualify" it in the class in which you want to call it. Qualifying a member means you must give its complete location, including the name of its class and the namespace (if any) in which its class was created. Here is an example:

using System;

public class Book
{
        public static string Title;
        public static string Author;
        public short YearPublished;
        public int     NumberOfPages;
        public char  CoverType;
}

public class Program
{
        static void Main()
        {
            Book First = new Book();

            Book.Title     = "Psychology and Human Evolution";
            Book.Author = "Jeannot Lamm";
            First.YearPublished = 1996;
            First.NumberOfPages = 872;
            First.CoverType     = 'H';

            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:  {0}", Book.Title);
            Console.WriteLine("Author: {0}", Book.Author);
            Console.WriteLine("Year:   {0}", First.YearPublished);
            Console.WriteLine("Pages:  {0}", First.NumberOfPages);
            Console.WriteLine("Cover:  {0}\n", First.CoverType);

            Book Second = new Book();

            Book.Title = "C# First Step";
            Book.Author = "Alexandra Nyango";
            Second.YearPublished = 2004;
            Second.NumberOfPages = 604;
            Second.CoverType = 'P';

            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:  {0}", Book.Title);
            Console.WriteLine("Author: {0}", Book.Author);
            Console.WriteLine("Year:   {0}", Second.YearPublished);
            Console.WriteLine("Pages:  {0}", Second.NumberOfPages);
            Console.WriteLine("Cover:  {0}\n", Second.CoverType);

            Console.ReadLine();
        }
}

Notice that when a member variable has been declared as static, you don't need an instance of the class to access that member variable outside of the class. Based on this, if you declare all members of a class as static, you don't need to declare a variable of their class in order to access them. In the following example, the Title and Author fields of the Book class are accessed from the Program class without using an instance of the Book class:

using System;

public class Book
{
        public static string Title;
        public static string Author;
}

public class Program
{
        static void Main()
        {
            Book.Title = "Psychology and Human Evolution";
            Book.Author = "Jeannot Lamm";
           
            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:  {0}", Book.Title);
            Console.WriteLine("Author: {0}\n", Book.Author);

            Book.Title = "C# First Step";
            Book.Author = "Alexandra Nyango";

            Console.WriteLine("Book Characteristics");
            Console.WriteLine("Title:  {0}", Book.Title);
            Console.WriteLine("Author: {0}\n", Book.Author);

            Console.ReadLine();
        }
}

As we saw in Lesson 6, you can also declare member variables of the main class as static. If you are referring to a static member variable in the same class in which it was declared, you don't have to qualify it. Here is an example:

using System;

public class NewProject
{
	static double Length;
	static double Width;

	static void Main()
	{
		Console.WriteLine("Rectangles Characteristics");

		Length = 22.55;
		Width = 20.25;

		Console.WriteLine("\nRectangle 1");
		Console.Write("Length: ");
		Console.WriteLine(Length);
		Console.Write("Width:  ");
		Console.WriteLine(Width);

		Length = 254.04;
		Width = 408.62;

		Console.WriteLine("\nRectangle 2");
		Console.Write("Length: ");
		Console.WriteLine(Length);
		Console.Write("Width:  ");
		Console.WriteLine(Width);

		Console.WriteLine();
	}
}

Practical Learning Practical Learning: Using Static Fields

  1. To use static fields, change the program as follows:
     
    using System;
    
    class IceCream
    {
    	public const decimal BasePrice     = 1.05M;
    	public const string  DefaultFlavor = "Diet Mint Fudge High Carb";
    	
    	public static char Flavor;
    	public static char Container;
    	public static char Ingredient;
    	public static int Scoops;
    	public static decimal TotalPrice;
    }
    
    class Exercise
    {
    	static void Main()
    	{
    		Console.WriteLine("Ice Cream Vendor Machine");
    		Console.WriteLine("What type of flavor do you want?");
    		Console.WriteLine("a - French Vanilla");
    		Console.WriteLine("b - Strawberry Vanilla");
    		Console.WriteLine("c - Butter Pecan");
    		Console.WriteLine("d - Cream of Cocoa");
    		Console.Write("Your Choice? " );
    		IceCream.Flavor = char.Parse(Console.ReadLine());
    
    		Console.WriteLine("What type of container do you want?");
    		Console.WriteLine("1 - Cone\n2 - Cup\n3 - Bowl");
    		Console.Write("Your Choice? ");
    		IceCream.Container = char.Parse(Console.ReadLine());
    
    		Console.WriteLine("Do you want an ingredient or not");
    		Console.WriteLine("0 - No Ingredient");
    		Console.WriteLine("1 - Peanuts");
    		Console.WriteLine("2 - M & M");
    		Console.WriteLine("3 - Cookies");
    		Console.Write("Your Choice? ");
    		IceCream.Ingredient = char.Parse(Console.ReadLine());
    
    		Console.Write("How many scoops(1, 2, or 3)? ");
    		IceCream.Scoops = int.Parse(Console.ReadLine());
    		IceCream.TotalPrice = IceCream.BasePrice * IceCream.Scoops;
    
    		
    		Console.WriteLine("\nIce Cream Order");
    		switch(IceCream.Flavor)
    		{
    			case 'a':
    			case 'A':
    				Console.WriteLine("Flavor:      French Vavilla");
    				break;
    			case 'b':
    			case 'B':
    				Console.WriteLine("Flavor:      Strawberry Vanilla");
    				break;
    			case 'c':
    			case 'C':
    				Console.WriteLine("Flavor:      Butter Pecan");
    				break;
    			case 'd':
    			case 'D':
    				Console.WriteLine("Flavor:      Cream of Cocoa");
    				break;
    			default:
    				Console.WriteLine("Confused Flavor - {0}", IceCream.DefaultFlavor);
    				break;
    		}
    	
    		switch(IceCream.Container)
    		{
    			case '1':
    				Console.WriteLine("Container:   Cone");
    				break;
    			case '2':
    				Console.WriteLine("Container:   Cup");
    				break;
    			case '3':
    				Console.WriteLine("Container:   Bowl");
    				break;
    			default:
    				Console.WriteLine("Container:   Cone");
    				break;
    		}
    		
    		switch(IceCream.Ingredient)
    		{
    			case '0':
    				Console.WriteLine("Ingredient:  None");
    				break;
    			case '1':
    				Console.WriteLine("Ingredient:  Peanuts");
    				break;
    			case '2':
    				Console.WriteLine("Ingredient:  M & M");
    				break;
    			case '3':
    				Console.WriteLine("Ingredient:  Cookies");
    				break;
    			default:
    				Console.WriteLine("Ingredient:  None");
    				break;
    		}
    
    		Console.WriteLine("Scoops:      {0}",   IceCream.Scoops);
    		Console.WriteLine("Total Price: {0:C}", IceCream.TotalPrice);
    		Console.WriteLine();
    	}
    }
  2. Save the file, compile and test it at the Command Prompt. Here is an example:
  3. Return to Notepad

Static Methods

Like a member variable, a method of a class can be define as static. This means that this particular method can access any member of the class regardless of the instance if there are many instances of the class declared.

To define a method as static, type the static keyword to its left. Here is an example:

using System;

public class Book
{
	private static string Title;
	static private string Author;
	private static int    Pages;
	static private double Price;

	static public void CreateBook()
	{
		Title  = "Psychology and Human Evolution";
		Author = "Jeannot Lamm";
		Pages  = 472;
		Price  = 24.95;
	}

	static public void ShowBook()
	{
		Console.WriteLine("Book Characteristics");
		Console.WriteLine("Title:  {0}", Book.Title);
		Console.WriteLine("Author: {0}", Book.Author);
		Console.WriteLine("Pages:  {0}", Pages);
		Console.WriteLine("Price:  {0:C}\n", Price);
	}
}

public class Program
{
	static void Main()
	{
		Book.CreateBook();
		Book.ShowBook();
	}
}

This would produce:

Book Characteristics
Title:  Psychology and Human Evolution
Author: Jeannot Lamm
Pages:  472
Price:  $24.95

The ReadLine(), the Write(), and the WriteLine() methods of the Console class that we have used so far are examples of static methods. There are many others in the C# language. The documentation can guide you to know what method of what class is static or not.

 

Practical Learning Practical Learning: Using Static Methods

  1. To use static methods, change the file as follows:
     
    using System;
    
    class IceCream
    {
    	public const decimal BasePrice     = 1.05M;
    	public const string  DefaultFlavor = "Diet Mint Fudge High Carb";
    	
    	private static char Flavor;
    	private static char Container;
    	private static char Ingredient;
    	private static int Scoops;
    	private static decimal TotalPrice;
    
    	public static void ProcessAnOrder()
    	{
    		Console.WriteLine("Ice Cream Vendor Machine");
    		Console.WriteLine("What type of flavor do you want?");
    		Console.WriteLine("a - French Vanilla");
    		Console.WriteLine("b - Strawberry Vanilla");
    		Console.WriteLine("c - Butter Pecan");
    		Console.WriteLine("d - Cream of Cocoa");
    		Console.Write("Your Choice? " );
    		IceCream.Flavor = char.Parse(Console.ReadLine());
    
    		Console.WriteLine("What type of container do you want?");
    		Console.WriteLine("1 - Cone\n2 - Cup\n3 - Bowl");
    		Console.Write("Your Choice? ");
    		IceCream.Container = char.Parse(Console.ReadLine());
    
    		Console.WriteLine("Do you want an ingredient or not");
    		Console.WriteLine("0 - No Ingredient");
    		Console.WriteLine("1 - Peanuts");
    		Console.WriteLine("2 - M & M");
    		Console.WriteLine("3 - Cookies");
    		Console.Write("Your Choice? ");
    		IceCream.Ingredient = char.Parse(Console.ReadLine());
    
    		Console.Write("How many scoops(1, 2, or 3)? ");
    		IceCream.Scoops = int.Parse(Console.ReadLine());
    		IceCream.TotalPrice = IceCream.BasePrice * IceCream.Scoops;
    	}
    
    	public static void DisplayReceipt()
    	{
    		Console.WriteLine("\nIce Cream Order");
    		switch(IceCream.Flavor)
    		{
    			case 'a':
    			case 'A':
    				Console.WriteLine("Flavor:      French Vavilla");
    				break;
    			case 'b':
    			case 'B':
    				Console.WriteLine("Flavor:      Strawberry Vanilla");
    				break;
    			case 'c':
    			case 'C':
    				Console.WriteLine("Flavor:      Butter Pecan");
    				break;
    			case 'd':
    			case 'D':
    				Console.WriteLine("Flavor:      Cream of Cocoa");
    				break;
    			default:
    				Console.WriteLine("Confused Flavor - {0}", IceCream.DefaultFlavor);
    				break;
    		}
    	
    		switch(IceCream.Container)
    		{
    			case '1':
    				Console.WriteLine("Container:   Cone");
    				break;
    			case '2':
    				Console.WriteLine("Container:   Cup");
    				break;
    			case '3':
    				Console.WriteLine("Container:   Bowl");
    				break;
    			default:
    				Console.WriteLine("Container:   Cone");
    				break;
    		}
    		
    		switch(IceCream.Ingredient)
    		{
    			case '0':
    				Console.WriteLine("Ingredient:  None");
    				break;
    			case '1':
    				Console.WriteLine("Ingredient:  Peanuts");
    				break;
    			case '2':
    				Console.WriteLine("Ingredient:  M & M");
    				break;
    			case '3':
    				Console.WriteLine("Ingredient:  Cookies");
    				break;
    			default:
    				Console.WriteLine("Ingredient:  None");
    				break;
    		}
    
    		Console.WriteLine("Scoops:      {0}",   IceCream.Scoops);
    		Console.WriteLine("Total Price: {0:C}", IceCream.TotalPrice);
    	}
    }
    
    class Exercise
    {
    	static void Main()
    	{
    		IceCream.ProcessAnOrder();
    		IceCream.DisplayReceipt();
    
    		Console.WriteLine();
    	}
    }
  2. Save, compile, and test the file
  3. Return to Notepad

this Instance

We have mentioned two techniques of accessing the members of a class, one consisted of declaring a variable of the class, the other had to do with static members. None of these techniques is important if you want to access a field or method of a class from another method of the same class. We know already that the members of a class are made available to all other members of the same class without being declared or qualified. Consider the following class:

class Triangle
{
	double Base;
	double Height;
	double Area;

	void Show()
	{
		double Area;

		Area = Base * Height / 2;
	}
}

When the Area variable is used in the Show() method, there are two variables available and named Area. It makes it confusing to know what particular variable is being accessed. C#, like many other languages, provides a special member of a class that allows you to specify the member of a class when accessing it. This member is called this.

When using the this member variable (in C/C++, it is a pointer), you can access any member of a class within any method of the same class. Here is an example:

using System;

class Triangle
{
	double Base;
	double Height;

	public void Show()
	{
		double Area;

		// Using "this" to access the members of this class
		this.Base = 24.55;
		this.Height = 20.75;

		// You cannot use this to access Area because Area 
		// is not a member of this class
		Area = this.Base * this.Height / 2;

		Console.WriteLine("Triangle Characteristics");
		Console.WriteLine("Base:   {0}", this.Base);
		Console.WriteLine("Height: {0}", this.Height);
		Console.WriteLine("Area:    {0}", Area);
	}
}

class Exercise
{
	static void Main()
	{
		Triangle tri = new Triangle();
		tri.Show();
	}
}

This would produce:

Triangle Characteristics
Base:   24.55
Height: 20.75
Area:   254.70625

There are exceptions when using this:

  • The this member can never be declared: it is automatically implied when you create a class
  • this cannot be used in a class A to access a member of class B. The following will cause an error:
     
    class Exercise
    {
    	static void Main()
    	{
    		Triangle tri = new Triangle();
    		this.tri.Show();
    	}
    }
  • this cannot be used in a static method. The following program will not compile because this is used in the Show() method declared as a static method:
     
    using System;
    
    class Triangle
    {
    	static double Base;
    	static double Height;
    
    	static public void Show()
    	{
    		double Area;
    
    		// Using "this" to access the members of this class
    		this.Base = 24.55;
    		this.Height = 20.75;
    
    		// You cannot use this to access Area because Area 
    		// is not a member of this class
    		Area = this.Base * this.Height / 2;
    
    		Console.WriteLine("Triangle Characteristics");
    		Console.WriteLine("Base:   {0}", this.Base);
    		Console.WriteLine("Height: {0}", this.Height);
    		Console.WriteLine("Area:   {0}", this.Area);
    	}
    }
    
    class Exercise
    {
    	static void Main()
    	{
    		Triangle.Show();
    	}
    }
 
 

Practical Learning Practical Learning: Using this

  1. To start a new file, on the main menu of Notepad, click File -> New
  2. In addition to what we have learned so far, to use this, type the following:
     
    using System;
    
    public class StoreItem
    {
    	private long   ItemNumber;
    	private string ItemName;
    	private double UnitPrice;
    
    	public void CreateAnItem(long nbr, string name, double price)
    	{
    		this.ItemNumber = nbr;
    		this.ItemName   = name;
    		this.UnitPrice  = price;
    	}
    
    	public void DisplayAnItem()
    	{
    		Console.WriteLine("Department Store");
    		Console.WriteLine("Item #:      {0}", this.ItemNumber);
    		Console.WriteLine("Description: {0}", this.ItemName);
    		Console.WriteLine("Unit Price:  {0:C}\n", this.UnitPrice);
    	}
    }
    
    public class Exercise
    {
    	static void Main()
    	{
    		StoreItem item = new StoreItem();
    
    		item.CreateAnItem(348649, "Men 3-Piece Jacket", 275.95);
    		item.DisplayAnItem();
    	}
    }
  3. Save the file in a new folder named DeptStore2
  4. Save the file itself as Exercise.cs
  5. Compile it at the Command Prompt and test it. This would produce:
     
    Department Store
    Item #:      348649
    Description: Men 3-Piece Jacket
    Unit Price:  $275.95
  6. Return to Notepad

Structures

 

Introduction

A structure is an enhanced version of the primitive data types we have used in previous lessons. The difference is that, like a class, a structure is created from one primitive type or by combining various primitive types, resulting in an advanced data type that is not inherently built in the C# language.

To create a structure, you use the same formula as a class but with the struct keyword. Here is an example of a structure:

struct Box
{
}

Like a class, a structure can have fields. They are listed in the body of the structure.

 

Practical Learning Practical Learning: Creating a Structure

  1. To create a structure, change the file as follows:
     
    using System;
    
    public struct StoreItem
    {
    	public long   ItemNumber;
    	public string ItemName;
    	public double UnitPrice;
    
    	public void DisplayAnItem()
    	{
    		Console.WriteLine("Department Store");
    		Console.WriteLine("Item #:      {0}", this.ItemNumber);
    		Console.WriteLine("Description: {0}", this.ItemName);
    		Console.WriteLine("Unit Price:  {0:C}\n", this.UnitPrice);
    	}
    }
    
    public class Exercise
    {
    	static void Main()
    	{
    	
    	}
    }
  2. Save the Exercise.cs file
 

Structure Declaration

Like any other data type, to use a structure, you can first declare a variable from it. Like primitive data types and unlike a class, a structure is a value type. Therefore, you can declare it without the new keyword. Here is an example:

using System;

struct Box
{
}

class DeptStore
{
	static void Main()
	{
		Box boite;
	}
}

Like the primitive data type, the memory for a variable of a structure is allocated on the stack but you can use the new operator to declare a structure:

using System;

struct Box
{
}

class DeptStore
{
	static void Main()
	{
		Box boite = new Box();

		Console.WriteLine();
	}
}

Although there are many similarities in the behaviors of classes and structures, you should use a structure when the object you are creating is meant to represent relatively small values.

Practical Learning Practical Learning: Declaring a Structure

  1. To declare and initialize a variable of a structure, change the file as follows:
     
    using System;
    
    public struct StoreItem
    {
    	public long   ItemNumber;
    	public string ItemName;
    	public double UnitPrice;
    
    	public void DisplayAnItem()
    	{
    		Console.WriteLine("Department Store");
    		Console.WriteLine("Item #:      {0}", this.ItemNumber);
    		Console.WriteLine("Description: {0}", this.ItemName);
    		Console.WriteLine("Unit Price:  {0:C}\n", this.UnitPrice);
    	}
    }
    
    public class Exercise
    {
    	static void Main()
    	{
    		StoreItem item;
    
    		item.ItemNumber = 348649;
    		item.ItemName   = "Men 3-Piece Jacket";
    		item.UnitPrice  = 275.95;
    
    		item.DisplayAnItem();
    	}
    }
  2. Save the Exercise.cs file
  3. Compile and execute it
 

Class Construction and Destruction

 

The Default Constructor

When you declare a variable of a class, a special method must be called to initialize the members of that class. This method is automatically provided for every class and it is called a constructor. Whenever you create a new class, a constructor is automatically provided to it. This  particular constructor is called the default constructor. You have the option of creating it or not. Although a constructor is created for your class, you can customize its behavior or change it tremendously.

A constructor holds the same name as its class and doesn't return any value, not even void. Here is an example:

public class Book
{
    Book()
}

Like every method, a constructor can be equipped with a body. In this body, you can access any of the member variables (or method(s)) of the same class. When introducing classes other than the main class, we saw that, to use such a class, you can declare its variable and allocate memory using the new operator. You can notice that we always included the parentheses when declaring such a variable. Here is an example:

public class Class1
{
    static void Main()
    {
	Exercise exo = new Exercise();
    }
}

In this case, the parentheses indicate that we are calling the default constructor to instantiate the class.

C++ Note
In C++, if you declare a class variable without having to initialize it, you can omit the parentheses.

Consider the following program:

using System;

public class Exercise
{
    public void Welcome()
    {
	Console.WriteLine("The wonderful world of C# programming");
    }

    public Exercise()
    {
	Console.WriteLine("The Exercise class is now available");
    }
}

public class Class1
{
    static void Main()
    {
	Exercise exo = new Exercise();
    }
}

When executed, it would produce:

The Exercise class is now available

This shows that, when a class has been instantiated, its constructor is the first method to be called. For this reason, you can use a constructor to initialize a class, that is, to assign default values to its member variables. When a constructor is used to initialize a variable declared for a class. That constructor is referred to as an instance constructor.

 

Practical Learning Practical Learning: Constructing a Class

  1. Start a new file in Notepad and, in the empty file, type the following:
     
    using System;
    
    public class Applicant
    {
    	public string FullName;
    	public string Address;
    	public string City;
    	public string State;
    	public string ZIPCode;
    	public string Sex;
    	public string DateOfBirth;
    	public int    Weight;
    	public string Height;
    	public int    Race;
    
    	public Applicant()
    	{
    		this.FullName = "Unknown";
    		this.Sex          = "Ungenerated";
    	}
    }
    
    public class Exercise
    {
    	public static int Main()
    	{
    		Applicant App = new Applicant();
    
    		Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
    		Console.WriteLine(" --- Driver's License Information ---");
    
    		Console.WriteLine("Full Name: {0}", App.FullName);
    		Console.WriteLine("Sex:           {0}\n", App.Sex);
    
    		return 0;
    	}
    }
  2. Save the file in a new folder named MVA1
  3. Save the file itself as Exercise.cs
  4. Switch to the Command Prompt and change the directory to the MVA1 folder that contains the current file
  5. Compile the program at the Command Prompt with
    csc Exercise.cs and execute it with Exercise. This would produce:
     
    -=- Motor Vehicle Administration -=-
     --- Driver's License Information ---
    Full Name:  Unknown
    Sex:           Ungenerated
  6. Return to Notepad
 

A Constructor With Argument

In the previous section, we saw that there is always a default constructor for a new class that you create; you just the option of explicitly creating one or not. The default constructor as we saw it doesn't take arguments: this is not a rule, it is simply assumed. Instead of a default constructor, you may want to create a constructor that takes an argument. Here is an example:

public class Quadrilateral
{
	public Quadrilateral(double side)
	{

	}
}

With this type of constructor, when you declare an instance of the class, you can use this new constructor to initialize the class. Here is an example:

using System;

public class Quadrilateral
{
	public Quadrilateral(double side)
	{

	}
}

public class Class1
{
	static void Main()
	{
		Quadrilateral Square = new Quadrilateral(6.55);
	}
}

If you create one constructor for your class and pass at least one argument to that constructor, the automatic default constructor created by the compiler disappears. This implies that if you declare an instance of the class and use the default constructor to initialize it, you would receive an error when you compiler the program. Based on this rule, the following program will not compile:

using System;

public class Quadrilateral
{
	public Quadrilateral(double side)
	{

	}
}

public class Class1
{
	static void Main()
	{
		Quadrilateral Square = new Quadrilateral();
	}
}

If you still want to use the default constructor in a class after creating a constructor that takes at least one argument, you must explicitly create that default constructor.

 

Practical Learning Practical Learning: Constructing a Class

  1. To pass an argument to a constructor, change the file as follows:
     
    using System;
    
    public class Applicant
    {
    	public string FullName;
    	public string Address;
    	public string City;
    	public string State;
    	public string ZIPCode;
    	public string Sex;
    	public string DateOfBirth;
    	public int    Weight;
    	public string Height;
    	public int    Race;
    
    	public Applicant(string n)
    	{
    		this.FullName = n;
    	}
    }
    
    public class Exercise
    {
    	static Applicant RegisterPersonalInformation()
    	{
    		string name;
    		char   sex;
    		string gender = null;
    
    		Console.WriteLine("Applicant's Registration");
    		Console.Write("Full Name: ");
    		name = Console.ReadLine();
    
    		do 
    		{
    			Console.Write("Sex(F=Female/M=Male): ");
    			sex = char.Parse(Console.ReadLine());
    		
    			if( (sex != 'f') && (sex != 'F') && (sex != 'm') && (sex != 'M') )
    				Console.WriteLine("Please enter a valid character");
    		}while( (sex != 'f') && (sex != 'F') && (sex != 'm') && (sex != 'M') );
    
    		if( (sex == 'f') || sex == 'F' )
    			gender = "Female";
    		else if( (sex == 'm') || (sex == 'M') )
    			gender = "Male";
    		
    		Applicant person = new Applicant(name);
    		person.Sex = gender;
    
    		return person;
    	}
    
    	public static int Main()
    	{
    		Console.WriteLine(" -=- Motor Vehicle Administration -=-");
    		Console.WriteLine(" --- Driver's License Application ---");
    
    		Applicant App = RegisterPersonalInformation();
    
    		Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
    		Console.WriteLine(" --- Driver's License Information ---");
    
    		Console.WriteLine("Full Name:   {0}", App.FullName);
    		Console.WriteLine("Sex:         {0}\n", App.Sex);
    
    		return 0;
    	}
    }
  2. Save, compile, and execute the program. Here is an example:
     
    -=- Motor Vehicle Administration -=-
     --- Driver's License Application ---
    Applicant's Registration
    Full Name: Ernestine Koullah
    Sex(F=Female/M=Male): G
    Please enter a valid character
    Sex(F=Female/M=Male): F
    
     -=- Motor Vehicle Administration -=-
     --- Driver's License Information ---
    Full Name:   Ernestine Koullah
    Sex:         Female
  3. Return to Notepad

Static Constructors

Like the above described instance constructors, a static constructor is used to initialize a class. The main difference is that a static constructor works internally, in the class. Therefore, it is not used to initialize a variable of the class and you can never declare a variable of a class using a static constructor.

To make a constructor static, when creating it, type the static keyword to its left. Here is an example:

using System;

public class Quadrilateral
{
	static Quadrilateral()
	{

	}
}

public class Class1
{
	static void Main()
	{
		// Use the default constructor to initialize an instance of the class
		Quadrilateral Square = new Quadrilateral();
	}
}

In the above class, a static constructor is created for the class but the default constructor is still available and it is used to instantiate the class.

Constructor Overloading

A constructor is the primary method of a class. It allows the programmer to initialize a variable of a class when the class is instantiated. A constructor that plays this role of initializing an instance of a class is also called an instance constructor. Most of the time, you don't even need to create a constructor, since one is automatically provided to any class you create. Sometimes too, as we have seen in some classes, you need to create your own class as you judge it necessary. And sometimes, a single constructor may not be sufficient. For example, when creating a class, you may decide, or find out, that there must be more than one way for a user to initialize a variable.

Like any other method, a constructor can be overloaded. In other words, you can create a class and give it more than one constructor. The same rules used on overloading regular methods also apply to constructors: the different constructors must have different number of arguments or a different number of arguments.

 

Practical Learning Practical Learning: Overloading a Constructor

  1. To overload the constructor, change the file as follows:
     
    using System;
    
    public class Applicant
    {
    	public string FullName;
    	public string Address;
    	public string City;
    	public string State;
    	public string ZIPCode;
    	public string Sex;
    	public string DateOfBirth;
    	public int    Weight;
    	public string Height;
    	public int    Race;
    
    	// The default constructor, used to initialize an 
    	// Applicant instance without much information
    	public Applicant()
    	{
    		this.FullName = "Unknown";
    		this.Sex          = "Ungenerated";
    	}
    
    	// A constructor that is passed only one argument
    	public Applicant(string n)
    	{
    		this.FullName = n;
    	}
    
    	// A constructor with more than one argument
    	// This type is suitable to completely initialize a variable
    	public Applicant(string n, string s, string dob)
    	{
    		this.FullName = n;
    		this.Sex      = s;
    		this.DateOfBirth = dob;
    	}
    }
    
    public class Exercise
    {
    	static Applicant RegisterPersonalInformation()
    	{
    		string name;
    		char   sex;
    		string gender = null;
    		string dob;
    
    		
    		Console.WriteLine(" -=- Motor Vehicle Administration -=-");
    		Console.WriteLine("Applicant's Registration");
    		Console.Write("Full Name: ");
    		name = Console.ReadLine();
    
    		do 
    		{
    			Console.Write("Sex(F=Female/M=Male): ");
    			sex = char.Parse(Console.ReadLine());
    		
    			if( (sex != 'f') && (sex != 'F') && (sex != 'm') && (sex != 'M') )
    				Console.WriteLine("Please enter a valid character");
    		}while( (sex != 'f') && (sex != 'F') && (sex != 'm') && (sex != 'M') );
    
    		if( (sex == 'f') || sex == 'F' )
    			gender = "Female";
    		else if( (sex == 'm') || (sex == 'M') )
    			gender = "Male";
    		
    		Console.Write("Date of Birth(mm/dd/yyyy): ");
    		dob = Console.ReadLine();
    
    		Applicant person = new Applicant(name, gender, dob);
    
    		return person;
    	}
    
    	static void Show(Applicant person)
    	{
    		Console.WriteLine("\n -=- Motor Vehicle Administration -=-");
    		Console.WriteLine(" --- Applicant's Personal Information ---");
    		Console.WriteLine("Full Name:     {0}", person.FullName);
    		Console.WriteLine("Sex:           {0}", person.Sex);
    		Console.WriteLine("Date of Birth: {0}\n", person.DateOfBirth);
    	}
    
    	public static int Main()
    	{
    		Applicant App = new Applicant();
    
    		App = RegisterPersonalInformation();
    		Show(App);
    
    		return 0;
    	}
    }
  2. Save, compile, and test the file. Here is an example:
     
    -=- Motor Vehicle Administration -=-
    Applicant's Registration
    Full Name: Dominique Monay
    Sex(F=Female/M=Male): d
    Please enter a valid character
    Sex(F=Female/M=Male): M
    Date of Birth(mm/dd/yyyy): 06/10/1972
    
     -=- Motor Vehicle Administration -=-
     --- Applicant's Personal Information ---
    Full Name:     Dominique Monay
    Sex:           Male
    Date of Birth: 06/10/1972
  3. Return to Notepad

The Destructor of a Class

While a constructor is a method used to initialize an instance of a class, a destructor is used to destruct an instance of class when that variable is not used anymore. Like the constructor, the destructor has the same name as the class. To indicate that the method is a destructor, its name is preceded with a tilde.

Here is an example of a destructor in a class:

using System;

class SampleClass
{
	// Constructor
	public SampleClass()
	{
		Console.WriteLine("SampleClass - Constructor");
	}

	~SampleClass()
	{
		Console.WriteLine("Destructor of SampleClass");
	}
}

public class NewProject
{
	
	static void Main()
	{
		SampleClass Sample = new SampleClass();

		Console.WriteLine();
	}
}

This would produce:

SampleClass - Constructor

Destructor of SampleClass

Like a (default) constructor, a destructor is automatically created for your class but you can also create it if you want. A class can have only one constructor. If you don't create it, the compiler would create it for your class. If you create it, the compiler would not create another. A destructor cannot have an access level. A destructor is called when the memory that a class was used is no longer needed. This is done automatically by the compiler. For this reason, you will hardly need to create a constructor, since its job is automatically taken care of behind the scenes by the compiler.

 

Previous Copyright 2004-2005 FunctionX, Inc. Next