Properties are a new language feature introduced with C#. They provide
the opportunity to protect a field in a class by reading and writing to it
through the property. In other languages, this is accomplished by programs
implementing specialized getter and setter methods. C# properties enable
this type of protection while also letting you access the property just like it
was a field. To get an appreciation for what properties accomplish, let's
take a look at how to provide field encapsulation by traditional methods.
Listing 10-1. An Example of Traditional Class Field Access:
Accessors.cs
using System;
public class
PropertyHolder
{
private
int someProperty =
0;
public
int getSomeProperty()
{
return someProperty;
}
public void
setSomeProperty(int
propValue)
{
someProperty = propValue;
}
}
public class
PropertyTester
{
public
static int
Main(string[] args)
{
PropertyHolder propHold = new
PropertyHolder();
propHold.setSomeProperty(5);
Console.WriteLine("Property
Value: {0}", propHold.getSomeProperty());
return
0;
}
}
Listing 10-1 shows the traditional method of accessing class fields.
The PropertyHolder class has the field we're interested in accessing. It
has two methods, getSomeProperty and setSomeProperty. The getSomeProperty
method returns the value of the someProperty field. The setSomeProperty
method sets the value of the someProperty field.
The PropertyTester class uses the methods of the PropertyHolder class to get
the value of the someProperty field in the PropertyHolder class. The Main
method instantiates a new PropertyHolder object, propHold. Next it sets
the someMethod of propHold to the value 5 by using the setSomeProperty
method. Then the program prints out the property value with a
Console.WriteLine method call. The argument used to obtain the value of
the property is a call to the getSomeProperty method of the propHold
object. It prints out "Property Value: 5" to the console.
This method of accessing information in a field has been good because it
supports the object-oriented concept of encapsulation. If the
implementation of someProperty changed from an int type to a byte type, this
would still work. Now the same thing can be accomplished much smoother
with properties.
Listing 10-2. Accessing Class Fields With Properties:
Properties.cs
using System;
public class
PropertyHolder
{
private
int someProperty =
0;
public
int SomeProperty
{
get
{
return someProperty;
}
set
{
someProperty
= value;
}
}
}
public class
PropertyTester
{
public
static int
Main(string[] args)
{
PropertyHolder propHold = new
PropertyHolder();
propHold.SomeProperty = 5;
Console.WriteLine("Property
Value: {0}", propHold.SomeProperty);
return
0;
}
}
Listing 10-2 shows how to create and use a property. The PropertyHolder
class has the "SomeProperty" property implementation. Notice
that the first letter of the first word is capitalized. That's the only
difference between the names of the property "SomeProperty" and the
field "someProperty". The property has two accessors, get and
set. The get accessor returns the value of the someProperty field.
The set accessor sets the value of the someProperty field with the contents of
"value". The "value" shown in the set accessor is a C#
reserved word. It's normally an error to use the "value" keyword
in any other context.
The PropertyTester class uses the SomeProperty property in the PropertyHolder
class. The first line of the Main method creates a PropertyHolder object
named propHold. Next the value of the someProperty field of the propHold
object is set to 5 by using the SomeProperty property. It's that simple --
just assign the value to the property as if it were a field.
After that, the Console.WriteLine method prints the value of the someProperty
field of the propHold object. It does this by using the SomeProperty
property of the propHold object. Again, it's that simple -- just use the
property as if it were a field itself.
Properties can be made read-only. This is accomplished by having only a
get accessor in the property implementation.
Listing 10-3. Read-Only Property: ReadOnlyProperty.cs
using System;
public class
PropertyHolder
{
private
int someProperty =
0;
public
PropertyHolder(int
propVal)
{
someProperty = propVal;
}
public int
SomeProperty
{
get
{
return someProperty;
}
}
}
public class
PropertyTester
{
public
static int
Main(string[] args)
{
PropertyHolder propHold = new
PropertyHolder(5);
Console.WriteLine("Property
Value: {0}", propHold.SomeProperty);
return 0;
}
}
Listing 10-3 shows how to implement a read-only property. The
PropertyHolder class has a SomeProperty property that only implements a get
accessor. It leaves out the set accessor. This particular
PropertyHolder class has a constructor which accepts an integer parameter.
The Main method of the PropertyTester class creates a new PropertyHolder
object named propHold. The instantiation of the propHold object uses the
constructor of the PropertyHolder that takes an int parameter. In this
case, it's set to 5. This initializes the someProperty field of the
propHold object to 5.
Since the SomeProperty property of the PropertyHolder class is read-only,
there is no other way to set the value of the someProperty field. If you
inserted "propHold.SomeProperty = 7" into the listing, the program
would not compile, because SomeProperty is read-only. When the
SomeProperty property is used in the Console.WriteLine method, it works
fine. This is because it's a read operation which only invokes the get
accessor of the SomeProperty property.
Listing 10-4. Write-Only Property: WriteOnlyProperty.cs
using System;
public class
PropertyHolder
{
private
int someProperty =
0;
public
int SomeProperty
{
set
{
someProperty
= value;
Console.WriteLine("someProperty is equal to {0}", someProperty);
}
}
}
public class
PropertyTester
{
public
static int
Main(string[] args)
{
PropertyHolder propHold = new
PropertyHolder();
propHold.SomeProperty = 5;
return 0;
}
}
Listing 10-4 shows how to create and use a write-only property. This
time the get accessor is removed from the SomeProperty property of the
PropertyHolder class. The set accessor has been added, with a bit more
logic. It prints out the value of the someProperty field after it's been
modified.
The Main method of the PropertyTester class instantiates the PropertyTester
class with a default constructor. Then it uses the SomeProperty property
of the propHold object to set the someProperty field of the propHold object to
5. This invokes the set accessor of the propHold object, which sets the
value of it's someProperty field to 5 and then prints "someProperty is
equal to 5" to the console.
In summary, you now know what properties are for and how they're used.
You have a feeling for the difference between using properties and traditional
techniques using class methods. Properties can be made read-only or
write-only and you know how to implement each type.
I invite you to return for Lesson 11: Indexers.
Your feedback is very important and I appreciate any constructive
contributions you have. Please feel free to contact me for any questions or
comments you may have about this lesson.
Feedback
Copyright © 2001 C# Station, All Rights Reserved