c1.ID = 1234; //---OK---
You can also restrict the visibility of the get
and set
accessors. For example, the set
accessor of a public property could be set to private
to allow only members of the class to call the set
accessor, but any class could call the get
accessor. The following example demonstrates this:
public int ID {
get {
return _ID;
}
private set {
_ID = value;
}
}
In this code, the set
accessor of the ID property is prefixed with the private
keyword to restrict its visibility. That means that you now cannot assign a value to the ID
property but you can access it:
c.ID = 1234; //---error---
Console.WriteLine(c.ID); //---OK---
You can, however, access the ID
property anywhere within the Contact
class itself, such as in the Email
property:
public string Email {
get {
//...
this.ID = 1234;
//...
}
//...
}
Partial Methods (C# 3.0)
Earlier on, you saw that a class definition can be split into one or more class definitions. In C# 3.0, this concept is extended to methods — you can now have partial methods. To see how partial methods works, consider the Contact
partial class:
public partial class Contact {
//...
private string _Email;
public string Email {
get {
return _Email;
}
set {
_Email = value;
}
}
}
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 {
partial void LogEmail() {
//---code to send email to contact---
Console.WriteLine("Email set: {0}", _Email);
}
}
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 = "weimenglee@learn2develop.net";
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
Automatic Properties (C# 3.0)
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 automatic properties. The 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;
};
}
}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Email {get; set;}
}
Now there's no need for you to define private members to store the values of the properties. Instead, you just need to use the get
and set
keywords, and the compiler will automatically create the private members in which to store the properties values. If you decide to add filtering rules to the properties later, you can simply implement the set
and
get accessor of each property.
To restrict the visibility of the get
and set
accessor when using the automatic properties feature, you simply prefix the get or set accessor with the private
keyword, like this:
public string FirstName {get; private set;}
This statement sets the FirstName
property as read-only.
You might be tempted to directly convert these properties ( FirstName
, LastName
, and Email
) into public data members. But if you did that and then later decided to convert these public members into properties, you would need to recompile all of the assemblies that were compiled against the old class.
Читать дальше