Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба №1 / books / csharp_ebook.pdf
Скачиваний:
77
Добавлен:
03.03.2016
Размер:
3.69 Mб
Скачать

Programmers Heaven: C# School

5. Structures, Enumeration, Garbage Collection & Nested Classes

Lesson Plan

Today's lesson consists of four major topics: Structures, Enumeration, Garbage Collector and Nested Classes. We will cover these one by one.

Structures (struct)

Structures, denoted in C# by the struct keyword, are lightweight objects. Structures are very similar to classes in C#, but with the following properties:

A struct is useful for creating types that are used to hold data like Point, Rectangle, Color types.

A struct is of value type, contrary to classes which are of reference type. This means that structures are allocated on the stack and passed to methods by value, that is, by making their copies.

A struct may contain constructors (except for the no-argument constructor), fields, methods and properties just like in classes.

Like all value types, structs can neither inherit another class, nor can they be inherited.

A struct can implement interfaces.

Like every other type in C#, a struct is also implicitly inherited from the System.Object class.

Instances of a struct can be created with and without using the new keyword.

Most of the .Net framework types like System.Int32 (for int), System.Double (for double), System.Boolean (for bool), System.Byte (for byte),... are implemented as a struct. When kept small in size, a struct is more efficiently used by the system than a class.

Defining a struct

A struct is defined just like a class, using the struct keyword. Suppose, in a drawing application, we need a Point data type. Since this is a simple and lightweight type, we implement it as a struct.

struct Point

{

public double x; public double y;

public Point(int x, int y)

{

this.x = x; this.y = y;

99

Programmers Heaven: C# School

}

public override string ToString()

{

return "(" + x + ", " + y + ")";

}

}

Here, we have declared a struct named Point. Point contains two public fields, x and y, that represent the location of a Point in the coordinate system. We provide a public constructor to initialize the location of the point and we also override the ToString() method from the Object class, so that our point can be printed easily using the Console.WriteLine() method in the Main() method.

Instantiating the struct

A struct can be instantiated in three ways:

Using the new keyword and calling the default no-argument constructor.

Using the new keyword and calling a custom or user defined constructor.

Without using the new keyword.

As we mentioned earlier, we can not provide the no-argument constructor in a struct and if we try to do so, the compiler will generate an error. The compiler implicitly provides a default no-argument constructor for each struct which initializes the fields of a struct with their default values. In the following Main() method, we instantiate Point using the above mentioned three ways

class Test

{

static void Main()

{

Point pt = new Point();

Point pt1 = new Point(15, 20);

Point pt2;

// instantiation without using the new keyword

pt2.x

=

6;

 

pt2.y

=

3;

 

Console.WriteLine("pt = {0}", pt);

Console.WriteLine("pt1 = {0}", pt1);

Console.WriteLine("pt2 = {0}", pt2);

}

}

100

Programmers Heaven: C# School

The output of the program is:

pt = (0, 0)

pt1 = (15, 20)

pt2 = (6, 3)

Press any key to continue

Here, we have instantiated three Point objects. The first one (referenced by pt) is instantiated using new and a default no-argument constructor (implemented by the compiler) which zeroed all the fields. Thus, the first Point (pt) is printed as (0, 0). The second one (referenced by pt1) is instantiated using the new keyword and a custom (double, double) constructor. The point (pt1) is initialized with the specified value and thus printed as (15, 20) on the console. The third object (referenced by pt2) is created without using the new keyword (like implicit data types). Note that we first initialized all the fields of pt2 before using it (in the Console.WriteLine() method). Before using a struct created without the new keyword, all its fields must be explicitly initialized. Hence, the Point (pt2) printed out as (6, 3). Note that we wrote:

Console.WriteLine("pt = {0}", pt);

instead of:

Console.WriteLine("pt = {0}", pt.ToString());

Console.WriteLine() expects a string, but since we have overridden the ToString() method in our Point struct, the compiler will implicitly call the ToString() method when it expects a string in the

Console.WriteLine() method.

Let us play with our program to increase our understanding of a struct. If we don't initialize any of the fields of Point then:

101

Programmers Heaven: C# School

static void Main()

 

{

 

Point pt2;

 

pt2.x = 6;

 

// pt2.y = 3;

// line 1

Console.WriteLine("pt2 = {0}", pt2);

}

The compiler will generate an error on 'line 1'

Use of unassigned local variable 'pt2'

Now, let us make the fields of the point private and provide public properties to access them.

struct Point

{

private double x; private double y;

public Point(int x, int y)

{

this.x = x; this.y = y;

}

public double X

{

get { return x; } set { x = value; }

}

public double Y

{

get { return y; } set { y = value; }

}

public override string ToString()

{

return "(" + x + ", " + y + ")";

102

Programmers Heaven: C# School

}

}

Now, let us try to create an instance of the Point without using the new keyword

static void Main()

{

Point pt2; pt2.X = 6; pt2.Y = 3;

Console.WriteLine("pt2 = {0}", pt2);

}

Here, we have created an instance of Point (pt2), initialized its fields through their accessor properties and then attempted to use it in a Console.WriteLine() method. When we try to compile the program, the compiler generates an error:

Use of unassigned local variable 'pt2'

We did initialize the fields through properties, but why is the compiler still complaining? In fact, when instantiating a struct without the new keyword, we must first initialize its fields explicitly, without using any properties or methods. This means that you can't instantiate and use a struct without the new keyword unless all its fields are public (or accessible to you) and explicitly initialized.

Finally, let us try to define a no-argument constructor in a struct

struct Point

{

public double x; public double y;

public Point()

{

x = 3; y = 2;

}

public Point(int x, int y)

{

this.x = x; this.y = y;

103

Соседние файлы в папке books