#249 – Using a get Accessor to Clean up Property Data

It’s not always the case that when you read a property’s value, you want exactly the same value that you wrote to the property.

As an example, imagine that we have a Dog.ShowDogName property that lets us read/write our dog’s official “show dog” name.  Show dog names are titles, so each word should be capitalized.  For convenience, we’d like the client code to not worry about the capitalization, but have the class take care of it.

We store the property in its original non-capitalized state and then clean up the name by capitalizing it whenever the property is read.

        private string showDogName;
        public string ShowDogName
        {
            get
            {
                return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(showDogName);
            }

            set
            {
                showDogName = value;
            }
        }

Here’s an example of some client code using the new property:

            kirby.ShowDogName = "fitzgerald's rich socialite mister stinks-a-lot";

            // Fitzgerald's Rich Socialite Mister Stinks-A-Lot
            Console.WriteLine(kirby.ShowDogName);
Advertisements

#248 – Implementing a Property that Returns a Calculated Value

When implementing a property, you might sometimes want to define a property that returns a calculated value, rather than just returning the value of an internal field.

Below is an example.  We have a Dog class with Name and Age that each just wraps an internal field and are both read/write.  We also define an AgeInDogYears property, which is read-only and returns the dog’s age in dog years.

The Age property is defined to encapsulate a private age field.

        // Age in human years
        private int age;
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }

The AgeInDogYears property is read-only and returns the calculated dog-year age.

        // Age in dog years
        public float AgeInDogYears
        {
            get
            {
                float dogYearAge;

                if (age < 1)
                    dogYearAge = 0;
                else if (age == 1)
                    dogYearAge = 10.5f;
                else
                    dogYearAge = 21 + ((age - 2) * 4);

                return dogYearAge;
            }
        }

#247 – Implementing a Write-Only Property

You implement a write-only property in a class by implementing the set accessor, but not the get accessor.  This will allow client code to write the property’s value, but not read the current value.

Below is an example of a write-only property for the Dog class. The BarkPassword property can be written to, but not read back.  The class then uses the internal value of BarkPassword in the SecureBark method, to verify that the dog is allowed to bark.

        // Internal storage of secret name
        private string barkPassword;

        // Public property, write-only
        public string BarkPassword
        {
            set
            {
                barkPassword = value;
            }
        }

        // Bark method also sets lastBarked
        public void SecureBark(string password)
        {
            if (password == barkPassword)
                Console.WriteLine("{0}: Woof!", Name);
            else
                Console.WriteLine("Not allowed to bark");
        }

Here’s how we might use the new property:

            kirby.BarkPassword = "flotsam62!";

            kirby.SecureBark("notthepassword");

#246 – Implementing a Read-Only Property

You implement a read-only property in a class by implementing the get accessor, but not the set accessor.  This will allow client code to read the property’s value, but not write to it directly.

Below is an example of a read-only property for the Dog class.  The WhenLastBarked property returns a DateTime value indicating the last time that the Dog barked–i.e. the last time that someone called the Bark method.

    // Backing variable storing date/time last barked
    private DateTime lastBarked;

    // Public property, allows reading lastBarked
    public DateTime WhenLastBarked
    {
        get
        {
            return lastBarked;
        }
    }

    // Bark method also sets lastBarked
    public void Bark()
    {
        Console.WriteLine("{0}: Woof!", Name);
        lastBarked = DateTime.Now;
    }

We now have a property in the Dog class that we can read from, but not write to.

    kirby.Bark();
    DateTime whenHeBarked = kirby.WhenLastBarked;

#245 – Defining a Set Accessor for a Property

A set accessor for a property is the code that executes when the client of an object tries to write the property’s value.

The set accessor is defined using the set keyword.  The new property value is accessible using the value keyword, which is treated as a local variable having the same type as the property.

It’s common to store the value of a property in an internal private variable, known as the backing field.

In the example below, the set accessor for a property stores the new property value in the internal backing field whenever the property is written.  Note that the private variable and the public property name differ only in their case (name vs. Name).

    // Backing field--where the property value is actually stored
    private string name;

    public string Name
    {
        // Set accessor allows the property to be written
        set
        {
            name = value;
        }
    }

#244 – Defining a Get Accessor for a Property

A get accessor for a property is the code that executes when the client of the object tries to read the property’s value.

The get accessor is defined using the get keyword.  The get accessor should return a value of the same type as the property itself.  You often just return the value of an internal private variable, which is known as the backing field.

In the example below, we define a get accessor for a property and return the value of the internal backing field whenever the property is read.

    // Backing field--where the property value is actually stored
    private string name;

    public string Name
    {
        // Get accessor allows the property to be read
        get { return name; }
    }

Below is an example of the Name property being read.

    // Read the Name property
    string objectName = myObject.Name;

#243 – Property Get and Set Accessors

You can define a property in a class as a way of encapsulating a private field.  When declaring a property in a class, you define the property’s type, its name, and code for the property’s accessors.  The accessors are the means by which a user of the class reads and writes the property’s value.

When defining the accessors, you can have one of the following combinations:

  • Just a get accessor   (property is read-only)
  • Just a set accessor  (property is write-only)
  • Both get/set accessors  (property is read/write)

The get accessor defines the code that executes when some code tries to read the property’s value.

The set accessor defines the code that executes when a property value is written to.