Console.WriteLine("Fourth constructor");
}
}
The statement:
Contact c1 = new Contact(1234, "Wei-Meng", "Lee", "weimenglee@learn2develop.net");
prints the following output:
Second constructor
Third constructor
Fourth constructor
Static Constructors
If your class has static members, it is only sometimes necessary to initialize them before an object is created and used. In that case, you can add static constructors to the class. For example, suppose that the Contact
class has a public static
member count
to record the number of the Contact object created. You can add a static constructor to initialize the static member, like this:
public class Contact {
//...
public static int count;
static Contact() {
count = 0;
Console.WriteLine("Static constructor");
}
//---first constructor---
public Contact() {
count++;
Console.WriteLine("First constructor");
}
//...
}
When you now create instances of the Contact
class, like this:
Contact c1 = new Contact();
Contact c2 = new Contact();
Console.WriteLine(Contact.count);
the static constructor is only called once, evident in the following output:
Static constructor
First constructor
First constructor
2
Note the behavior of static constructors:
□ A static constructor does not take access modifiers or have parameters.
□ A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
□ A static constructor cannot be called directly.
□ The user has no control on when the static constructor is executed in the program.
Copy Constructor
The C# language does not provide a copy constructor that allows you to copy the value of an existing object into a new object when it is created. Instead, you have to write your own.
The following copy constructor in the Contact
class copies the values of the properties of an existing object (through the otherContact
parameter) into the new object:
class Contact {
//...
//---a copy constructor---
public Contact(Contact otherContact) {
this.ID = otherContact.ID;
this.FirstName = otherContact.FirstName;
this.LastName = otherContact.LastName;
this.Email = otherContact.Email;
}
//...
}
To use the copy constructor, first create a Contact object:
Contact c1 = new Contact(1234, "Wei-Meng", "Lee",
"weimenglee@learn2develop.net");
Then, instantiate another Contact object and pass in the first object as the argument:
Contact c2 = new Contact(c1);
Console.WriteLine(c2.ID); //---1234---
Console.WriteLine(c2.FirstName); //---Wei-Meng---
Console.WriteLine(c2.LastName); //---Lee---
Console.WriteLine(c2.Email); //---weimenglee@learn2develop.net---
Object Initializers (C# 3.0)
Generally, there are two ways in which you can initialize an object — through its constructor(s) during instantiation or by setting its properties individually after instantiation. Using the Contact
class defined in the previous section, here is one example of how to initialize a Contact
object using its constructor:
Contact c1 = new Contact(1234, "Wei-Meng", "Lee", "weimenglee@learn2develop.net");
You can also set an object's properties explicitly:
Contact c1 = new Contact();
c1.ID = 1234;
c1.FirstName = "Wei-Meng";
c1.LastName = "Lee";
c1.Email = "weimenglee@learn2develop.net";
In C# 3.0, you have a third way of initializing objects — when they are instantiated. This feature is known as the object initializers. The following statement shows an example:
Contact c1 = new Contact() {
ID = 1234,
FirstName = "Wei-Meng",
LastName = "Lee",
Email = "weimenglee@learn2develop.net"
};
Here, when instantiating a Contact
class, you are also setting its properties directly using the {}
block. To use the object initializers, you instantiate an object using the new
keyword and then enclose the properties that you want to initialize within the {}
block. You separate the properties using commas.
Do not confuse the object initializer with a class's constructor(s). You should continue to use the constructor (if it has one) to initialize an object. The following example shows that you use the Contact
's constructor to initialize the ID
property and then the object initializers to initialize the rest of the properties:
Contact c2 = new Contact(1234) {
FirstName = "Wei-Meng",
LastName = "Lee",
Email = "weimenglee@learn2develop.net"
};
Destructors
In C#, a constructor is called automatically when an object is instantiated. When you are done with the object, the Common Language Runtime (CLR) will destroy them automatically, so you do not have to worry about cleaning them up. If you are using unmanaged resources, however, you need to free them up manually.
When objects are destroyed and cleaned up by the CLR, the object's destructor is called. A C# destructor is declared by using a tilde (~) followed by the class name:
class Contact : Object {
//---constructor---
public Contact() {
//...
}
//---destructor---
~Contact() {
//---release unmanaged resources here---
}
//...
}
The destructor is a good place for you to place code that frees up unmanaged resources, such as COM 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---
Читать дальше