Suppose you that want to allow users of this partial class to optionally log the email address of each contact when its Email
property is set. In that case, you can define a partial method — LogEmail()
in this example — like this:
public partial class Contact {
//...
}
public partial class Contact {
//...
private string _Email;
public string Email {
get {
return _Email;
}
set {
_Email = value;
LogEmail();
}
}
//---partial methods are private---
partial void LogEmail();
}
The partial method LogEmail()
is called when a contact's email is set via the Email
property. Note that this method has no implementation. Where is the implementation? It can optionally be implemented in another partial class. For example, if another developer decides to use the Contact
partial class, he or she can define another partial class containing the implementation for the LogEmail()
method:
public partial class Contact {
}
So when you now instantiate an instance of the Contact
class, you can set its Email
property as follows and a line will be printed in the output window:
Contact contact1 = new Contact();
contact1.Email = '[email protected]';
What if there is no implementation of the LogEmail()
method? Well, in that case the compiler simply removes the call to this method, and there is no change to your code.
Partial methods are useful when you are dealing with generated code. For example, suppose that the Contact
class is generated by a code generator. The signature of the partial method is defined in the class, but it is totally up to you to decide if you need to implement it.
A partial method must be declared within a partial class or partial struct.
Partial methods must adhere to the following rules:
□ Must begin with the partial
keyword and the method must return void
□ Can have ref
but not out
parameters
□ They are implicitly private, and therefore they cannot be virtual (virtual methods are discussed in the next chapter)
□ Parameter and type parameter names do not have to be the same in the implementing and defining declarations
In the Contact class
defined in the previous section, apart from the ID
property, the properties are actually not doing much except assigning their values to private members:
public string FirstName {
get {
return _FirstName;
}
set {
_FirstName = value;
}
}
public string LastName {
get {
return _LastName;
}
set {
_LastName = value;
}
}
public string Email {
get {
return _Email;
}
set {
_Email = value;
}
}
In other words, you are not actually doing any checking before the values are assigned. In C# 3.0, you can shorten those properties that have no filtering (checking) rules by using a feature known as Contact
class can be rewritten as:
public class Contact {
int _ID;
public int ID {
get {
return _ID;
}
set {
if (value > 0 && value <= 9999) {
_ID = value;
} else {
_ID = 0;
};
}
}