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

Programmers Heaven: C# School

In a similar manner, you can define many useful enumerations like days of the week (Sunday, Monday,…), name of the months (January, February,…), connection type (TCPIP, UDP), file open mode (ReadOnly, WriteOnly, ReadWrite, Append), etc.

More about Enumerations

Enumerations internally use integral values to represent the different named constants. The underlying type of an enumeration can be any integral type (e.g. int, byte, etc). The default type is int. In fact, when we declare an enumeration, its items are assigned successive integer values starting from zero. Hence, in our SortCriteria enumeration, the value of ByName is 0, the value of ByType is 1, the value of BySize is 2 and the value of ByDate is 3. We can convert the Enumeration data back to an integral value by applying an appropriate cast.

static void Main()

{

SortCriteria criteria = SortCriteria.ByType;

int i = (int) criteria;

Console.WriteLine("the integral value of {0} is {1}", criteria, i);

}

Here, we created an instance of SortCriteria (named criteria), type-casted it to int and then printed it using the Console.WriteLine() method. The output is:

the integral value of ByType is 1

Press any key to continue

You can see from the output that the integral value of SortCriteria.ByType is 1. Also note that when we printed the enumeration identifier (criteria), it printed the named constant (ByType) and not its value (1). We can also define the values for the Enumerator identifier explicitly while defining new enumerations, like:

enum Temperature

{

BoilingPoint = 100,

FreezingPoint = 0

}

Now, when we try to print the value of either Temperature.BolingPoint or Temperature.FreezingPoint, it will display the assigned values and not the default values (starting from zero and incrementing by one each time).

int i = (int) Temperature.BoilingPoint;

Console.WriteLine("the integral value of {0} is {1}", Temperature.BoilingPoint, i);

Will display:

108

Programmers Heaven: C# School

the integral value of BoilingPoint is 100

Press any key to continue

Consider the following enumeration

enum Days : byte

{

Monday = 1,

Tuesday,

Wednesday,

Thursday,

Friday,

Saturday,

Sunday

}

Here we have defined an enumeration for Days. Note that we assigned the value of 1 to Monday. Hence, the integral values for successive constants would be successive integers after 1 (that is, 2 for Tuesday, 3 for Wednesday and so on). Also, note that we specified the underlying type for the enumeration (Days) as a byte instead of the default int type. Now, the compiler will use the byte type to represent days internally.

enum Days : byte

{

...

}

In the Main() method, we can print the integral value of days as:

static void Main()

{

int i = (byte) Days.Tuesday;

Console.WriteLine("the integral value of {0} is {1}", Days.Tuesday, i);

}

The output is:

the integral value of Tuesday is 2

Press any key to continue

Finally, enumerations are of value type. They are created and stored on the stack and passed to the methods by making a copy of the value (by value).

109

Programmers Heaven: C# School

Garbage Collection in .Net

Memory management is no longer the responsibility of a programmer when writing managed code in the .Net environment. .Net provides its own Garbage Collector to manage the memory. The Garbage Collector is a program that runs in the background as a low-priority thread and keeps track of the un-referenced objects (objects that are no longer referenced by any reference) by marking them as 'dirty objects'. The Garbage collector is invoked by the

.Net Runtime at regular intervals and removes the dirty objects from memory.

Before re-claiming the memory of any object (before removing the object from memory), the garbage collector calls the Finalize() method or destructor (discussed in lesson 4) of the object, so as to allow an object to free its resources. Hence, you should provide the destructor (which internally overrides the Object class' Finalize() method) in your classes if you want to free some un-managed resources held by your objects. Since the Finalize() method is called by the Garbage Collector before re-claiming the object's memory, we never know exactly when it will be called. It may be called instantly, after an object is found to have no references to it, or later, when the CLR needs to re-claim some memory. You may optionally implement the IDisposable interface and override its Dispose() method if you want to allow the user of your class to specify (by calling the Dispose() method) when the resources occupied by the object should be freed. Although we haven't yet discussed interfaces, I will give an example of implementing the IDisposable interface, as you will have to use this method quite often in your programs. I recommend that you come back and read this again after you become familiar with interfaces.

using System;

namespace CSharpSchool

{

class Test

{

static void Main()

{

GarbageCollection garCol = new GarbageCollection(); garCol.DoSomething();

garCol.Dispose();

}

}

class GarbageCollection : IDisposable

{

public void DoSomething()

{

Console.WriteLine("Performing usual tasks...");

}

public void Dispose()

{

GC.SuppressFinalize(this);

110

Programmers Heaven: C# School

Console.WriteLine("Disposing object...");

Console.WriteLine("Freeing resources captured by this object...");

}

~GarbageCollection()

{

Console.WriteLine("Destructing object...");

Console.WriteLine("Freeing resources captured by this object...");

}

}

}

In the above example we have declared a class named GarbageCollection which implements the IDisposable interface and overrides its Dispose() method. Now, the user or client of the GrabageCollection class can decide when to free-up the resources held by the object, by calling the Dispose() method. The common usage of the class is demonstrated in the Test class' Main() method. Note that we called the SuppressFinalize() method of the System.GC class in the Dispose() method.

public void Dispose()

{

GC.SuppressFinalize(this);

Console.WriteLine("Disposing object...");

Console.WriteLine("Freeing resources captured by this object...");

}

The System.GC class can be used to control the Garbage Collector. If we pass the current object in the GC.SuppressFinalize() method, the Finalize() method (or destructor) of the current object won't be called. If we execute the above program, we will get the following output:

Performing usual tasks...

Disposing object...

Freeing resources captured by this object...

Press any key to continue

But, if we comment out the call to the Dispose() method in our Main() method.

static void Main()

{

GarbageCollection garCol = new GarbageCollection(); garCol.DoSomething();

//garCol.Dispose();

}

111

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