Account
Class with a Property Rather Than Set and Get MethodsOur first Account
class contained a private
instance variable name
and public
methods SetName
and GetName
that enabled a client to assign to and retrieve from an Account
’s name
, respectively. C# provides a more elegant solution—called properties—to accomplish the same tasks. A property encapsulates a set
accessor for storing a value into a variable and a get
accessor for getting the value of a variable.3 In this section, we’ll revisit the AccountTest
class to demonstrate how to interact with an Account
object containing a public Name
property, then we’ll present the updated Account
class and take a detailed look at properties.
AccountTest
Using Account’s Name
PropertyFigure 4.5 shows the updated AccountTest
class that uses class Account
’s Name
property (declared in Fig. 4.6) to get
and set
an Account
’s name
instance variable. This app produces the same output as the one in Fig. 4.1, assuming the user once again enters Jane Green
when prompted to enter a name.
Account
’s Name
Property to Get the NameThe get
accessor of the Account
class’s Name
property gets the account name stored in a particular Account
object. Line 13
Console.WriteLine($"Initial name is: {myAccount.Name}");
displays myAccount
’s initial name by accessing the object’s Name
property with the expression myAccount.Name
. To access a property, you specify the object’s name (myAccount
), followed by the member-access operator (.
) and the property’s name (Name
). When used to get the account’s name, this notation implicitly executes the property’s get
accessor, which returns the account’s name.
When Main
accesses the Name
property in line 13:
The app transfers program execution from the expression myAccount.Name
(line 13 in Main
) to the property Name
’s get
accessor).
Next, the Name
property’s get
accessor performs its task—that is, it returns (i.e., gives back) the value of myAccount
’s name
instance variable to line 13 where the property was accessed.
Console.WriteLine
displays the string
returned by the Name
property’s get
accessor—which was inserted into the interpolated string
in place of the expression myAccount.Name
—then the program continues executing at line 16 in Main
.
As in Fig. 4.1, line 13 does not display a name, because we have not yet stored a name in the myAccount
object.
Account
’s Name
Property to Set the NameNext, lines 16–17 prompt for and input a name. The set
accessor Account
class’s Name
property sets an account name in a particular Account
object. Line 18
myAccount.Name = theName; // put theName in myAccount's Name
assigns to myAccounts
’s Name
property the string
entered by the user in line 17. When property Name
is invoked by the expression myAccount.Name
on the left of an assignment:
The app transfers program execution from line 18 in Main
to Name
’s set
accessor.
Property Name
’s set
accessor performs its task—that is, it stores in the myAccount
object’s name
instance variable the string
value that was assigned to property Name
in Main
(line 18).
When Name
’s set
accessor completes execution, program execution returns to where the Name
property was accessed (line 18 in Main
), then execution continues at line 21.
To demonstrate that myAccount
now contains the name the user entered, line 21
Console.WriteLine($"myAccount"s name is: {myAccount.Name}");
accesses myAccounts
’s Name
property again, which uses the property’s get
accessor to obtain the name
instance variable’s new value. As you can see, the last line of the program’s output displays the name input from the user in line 17.
Account
Class with an Instance Variable and a PropertyThe updated Account
class replaces the GetName
and SetName
methods from Fig. 4.2 with the property Name
(lines 10–20 of Fig. 4.6). The property’s get
and set
accessors handle the details of getting and setting data, respectively. Unlike method names, the accessor names get
and set
each begin with a lowercase letter.
Name
’s DeclarationLine 10
public string Name
begins the Name
property declaration, which specifies that
the property is public
so it can be used by the class’s clients,
the property’s type is string
and
the property’s name is Name
.
By convention, a property’s identifier is the capitalized identifier of the instance variable that it manipulates—Name
is the property that represents instance variable name
. C# is case sensitive, so Name
and name
are distinct identifiers. The property’s body is enclosed in the braces at lines 11 and 20.
Name
’s get
AccessorThe get
accessor (lines 12–15) performs the same task as method GetName
in Fig. 4.2. A get
accessor begins with the keyword get
, and its body is delimited by braces (lines 13 and 15). Like method GetName
, the get
accessor’s body contains a return
statement (line 14) that returns the value of an Account
’s name
instance variable. So, in line 13 of Fig. 4.5
Console.WriteLine($"Initial name is: {myAccount.Name}");
the expression myAccount.Name
gets the value of myAccount
’s instance variable name
. The property notation allows the client to think of the property as the underlying data, but the client still cannot directly manipulate the private
instance variable name
. Keyword get
is a contextual keyword, because it’s a keyword only in a property’s context (that is, its body)—in other contexts, get
can be used as an identifier.
Name
’s set
AccessorThe set
accessor (lines 16–19, Fig. 4.6) begins with the identifier set
followed by its body, which is delimited by braces (lines 17 and 19). Method SetName
(Fig. 4.2) declared a parameter accountName
to receive the new name to store in an Account
object—a set
accessor uses the keyword value
(line 18, Fig. 4.6) for the same purpose. value
is implicitly declared and initialized for you with the value that the client code assigns to the property. So, in line 18 of Fig. 4.5
myAccount.Name = theName; // put theName in myAccount's Name
value
is initialized with theName
(the string
entered by the user). Property Name
’s set
accessor simply assigns value
to the instance variable name
—we’ll show a set
accessor that performs validation in Fig. 4.11. Like get
, the keywords set
and value
are contextual keywords—set
is a keyword only in a property’s context and value
is a keyword only in a set
accessor’s context.
Although contextual keywords, like value in a
set accessor, can be used as identifiers in some contexts, we prefer not to do so.
The statements inside the property in lines 14 and 18 (Fig. 4.6) each access name
even though it was declared outside the property declaration. We can use instance variable name
in class Account
’s property (and other properties and methods, if there are any), because name
is an instance variable in the same class.
Account
UML Class Diagram with a PropertyFigure 4.7 presents a UML class diagram for class Account
of Fig. 4.6. We model C# properties in the UML as attributes. The property Name
is listed as a public attribute—as indicated by the plus (+) sign—followed by the word “property” in guillemets («
and »
). Using descriptive words in guillemets (called stereotypes in the UML) helps distinguish properties from other attributes and operations. The UML indicates the type of the property by placing a colon and a type after the property name.
A class diagram helps you design a class, so it’s not required to show every implementation detail. Since an instance variable that’s manipulated by a property is really an implementation detail of that property, our class diagram does not show the name
instance variable. A programmer implementing the Account
class based on this class diagram would create the instance variable name
as part of the implementation process (as we did in Fig. 4.6). Similarly, a property’s get
and set
accessors are implementation details, so they’re not listed in the UML diagram.