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:
//...
~Contact() {
}
}
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.
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 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 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