objects or database handles. One important point is that you cannot call the destructor explicitly — it will be called automatically by the garbage collector.

To manually dispose of your unmanaged resources without waiting for the garbage collector, you can implement the IDisposable interface and the Dispose() method.

Chapter 5 discusses the concept of interfaces in more detail.

The following shows the Contact class implementing the IDisposable class and implementing the Dispose() method:

class Contact : IDisposable {

 //...

 ~Contact() {

  //-–-call the Dispose() method---

  Dispose();

 }

 public void Dispose() {

  //---release unmanaged resources here---

 }

}

You can now manually dispose of unmanaged resources by calling the Dispose() method directly:

Contact c1 = new Contact(); //...

//---done with c1 and want to dispose it---

c1.Dispose();

There is now a call to the Dispose() method within the destructor, so you must make sure that the code in that method is safe to be called multiple times — manually by the user and also automatically by the garbage collector.

The Using Statement

C# provides a convenient syntax for automatically calling the Dispose() method, using the using keyword. In the following example, the conn object is only valid within the using block and will be disposed automatically after the execution of the block.

using System.Data.SqlClient;

...

using (SqlConnection conn = new SqlConnection()) {

 conn.ConnectionString = '...';

 //...

}

Using the using keyword is a good way for you to ensure that resources (especially COM objects and unmanaged code, which will not be unloaded automatically by the garbage collector in the CLR) are properly disposed of once they are no longer needed.

Static Classes

You can also apply the static keyword to class definitions. Consider the following FilesUtil class definition:

public class FilesUtil {

 public static string ReadFile(string Filename) {

  //---implementation---

  return 'file content...';

 }

 public static void WriteFile(string Filename, string content) {

  //---implementation---

 }

}

Within this class are two static methods — ReadFile() and WriteFile(). Because this class contains only static methods, creating an instance of this class is not very useful, as Figure 4-4 shows.

Figure 4-4 

As shown in Figure 4-4, an instance of the FilesUtil class does not expose any of the static methods defined within it. Hence, if a class contains nothing except static methods and properties, you can simply declare the class as static, like this:

public static class FilesUtil {

 public static string ReadFile(string Filename) {

  //---implementation---

  return 'file content...';

 }

 public static void WriteFile(string Filename, string content) {

  //---implementation---

 }

}

The following statements show how to use the static class:

//---this is not allowed for static classes---

FilesUtil f = new FilesUtil();

//---these are OK---

Console.WriteLine(FilesUtil.ReadFile(@'C:TextFile.txt'));

FilesUtil.WriteFile(@'C:TextFile.txt', 'Some text content to be written');

Use static classes when the methods in a class are not associated with a particular object. You need not create an instance of the static class before you can use it.

System.Object Class

In C#, all classes inherit from the System.Object base class (inheritance is discussed in the next chapter). This means that all classes contain the methods defined in the System.Object class.

All class definitions that do not inherit from other classes by default inherit directly from the System.Object class. The earlier Contact class definition:

public class Contact

for example, is equivalent to:

public class Contact: Object

You can create an instance of the System.Object class if you want, but it is by itself not

Вы читаете C# 2008 Programmer's Reference
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату