Properties Fundamentals

Introduction

A property is a member of a class that plays an intermediary role to a field of the class. A property is used to "filter" access to a field of a class. Therefore, you start by declaring a (private (if you don't make it private, you may be deceiving the purpose of creating a property)) field. Here is an example:

@functions{
    public class Square
    {
        private double _side;
    }
}

Obviously this private field cannot be accessed by an outside class. To let the outside classes access this variable, you would/can create a property.

Practical LearningPractical Learning: Introducing Properties

  1. Save the following images to your computer:

    Tax Preparation

    Tax Preparation

  2. Start Microsoft Visual Studio. Create a new ASP.NET Core Web App named Geometry2. Uncheck the Configure For HTTPS check box
  3. In the Solution Explorer, right-click Geometry2 -> Add -> New Folder
  4. Type Models and press Enter
  5. To start a class, in the Solution Explorer, right-click Models -> Add -> Class...
  6. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the file Name to Square
  7. Click Add
  8. Change class as follows:
    namespace Geometry2.Models
    {
        public class Square
        {
            private double s;
    
            public void Initialize(double side)
            {
                s = side;
            }
        }
    }

Creating a Property

There is no single syntax to create a property but there is a general starting formula. The beginning of a property resembles a field, but a property has a body like that of a class. Therefore, a property starts with the following formula:

options data-type property-name { }

You start with one or more options. As seen with fields, the primary option to apply to a property is an access level. Like a field, a property can be made to be accessed by only the members of the same class or by objects outside the class. This means that you can start a property with an access level of private, public, or internal. Most of the time, you will apply the public access level.

Like a field, a property must have a name. The name of a property follows the rules and policies of names of classes. This means that the name should resemble that of an object and start with an uppercase letter.

Like a field, a property must indicate its type, as its data type. Remember that, so far, we have applied the int, the string, and the double types. You can apply one of those to a property you are creating.

Like a class, a property must have a body, which is delimited by curly brackets immediately after its name. Based on these descriptions, a property can start as follows:

@functions{
    public class Square
    {
        // This is a new property
        public double Side { }
    }
}

To make it easy to read, each curly bracket can be created on its own line. Here is an example:

@functions{
    public class Square
    {
        public double Side
        {
        }
    }
}

A Property in a Page Model

As we have seen in previous lessons, a razor page is created from a class, and it is derived from the built-in PageModel class. The class of a razor page is primarily a regular class like any other C# class. Therefore, in the razor page class, you can create a property using any of the techniques we will study in this and the future lessons.

Introduction to Property Readers

Overview

With regards to their roles, there are various types of properties.

A property is referred to as read if its role is to make available the value of the member variable it represents. To create a read property, in the body of the property, type a contextual keyword(contextual means the word is a keyword only in some cases, depending on how it is being used) named get. Then create a body for that keyword, using the traditional curly brackets that delimit a section of code. Here is an example:

@functions{
    public class Square
    {
        public double Side
        {
            get {}
        }
    }
}

Once again, to make your code easy to read, each curly bracket can be written on its own line. The section that contains get and its curly bracket is referred to as the get section, or the get clause, or the getter.

The get section behaves like a section of code that produces a value. We already know that, to indicate that a section of code produces a value, in the body of the section of code, type the return keyword.

When a section of code produces a result, it must produce a value that is the same type as the data type indicated in its beginning. When it comes to a property, its get section must produce a value that is the same type indicated before its name. Therefore, in the body of the get clause, you must type return followed by a value. The simplest way consists of returning the field that corresponds to the property in the class. Here is an example:

@functions{
    public class Square
    {
        private double _side;

        public double Side
        {
            get
            {
                return _side;
            }
        }
    }
}

In the same way, you can create as many get properties as you judge necessary. Otherwise, in the body of a get clause, you can implement any behavior you want such as performing some operations before making the field's value available outside.

ApplicationPractical Learning: Creating Property Readers

  1. Change the document as follows:
    namespace Geometry2.Models
    {
        public class Square
        {
            private double s;
    
            public void Initialize(double side)
            {
                s = side;
            }
    
            public double Side
            {
                get
                {
                    return s;
                }
            }
    
            public double Perimeter
            {
                get
                {
                    return s * 4;
                }
            }
    
            public double Area
            {
                get
                {
                    return s * s;
                }
            }
        }
    }
  2. In the Solution Explorer, right-click wwwroot -> Add -> New Folder
  3. Type images and press Enter
  4. In the Solution Explorer, right-click images -> Add -> Existing Item...
  5. Select each of the images you had saved earlier
  6. In the Solution Explorer, expand wwwroot
  7. In the Solution Explorer, below wwwroot, right-click css -> Add -> New Item...
  8. In the left list of the Add New Item dialog box, below ASP.NET Core, expand Web and click Content then, in the middle list, click Style Sheet
  9. Chang the file name to Geometry
  10. Click Add
  11. Change the document as follows:
    body {
    }
    
    .delimiter   { margin:      auto;
                   width:       450px; }
    .common-font { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  12. In the Solution Explorer, right-click Pages -> Add -> Razor Page...
  13. In the Add New Scaffolded Item dialog box, make sure Razor Page - Empty is selected.
    Click Add
  14. Change the file Name to Square
  15. Click Create

Accessing a Property Reader

After creating a property, you can use it. We saw that, before using a class, you can create an instance of the class, which consists of declaring a variable of the class. We also saw that, to access a member of a class, type the name of the object, a period, and the desired member. This is also done to access a property.

Practical LearningPractical Learning: Accessing a Property Reader

  1. Change the Square.cshtml document as follows:
    @page
    @model Geometry2.Pages.SquareModel
    @using Geometry2.Models
    @{
        Square sqr = new Square();
    
        if (Request.HasFormContentType)
        {
            double length = double.Parse(Request.Form["txtSide"]);
    
            sqr.Initialize(length);
        }
    }
    
    <h1 class="text-center common-font">Geometry - Square</h1>
    <hr />
    <p class="text-center"><img src="../images/Square1.png" width="414" height="492" /></p>
    <hr />
    <div class="delimiter common-font">
        <form name="frmGeometry" method="post">    
            <table class="table">
                <tr>            
                    <td width="125"><label for="txtSide">Side:</label></td>
                    <td><input type="text" id="txtSide" name="txtSide" value=@sqr.Side class="form-control" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td class="text-center"><input type="submit" value="Calculate" class="btn-primary" /></td>
                </tr>
            </table>
        </form>
        
        <h1 class="text-center common-font">Square Summary</h1>
        
        <table class="table">
            <tr>
                <td width="125">Perimeter:</td>
                <td>@sqr.Perimeter</td>
            </tr>
            <tr>
                <td>Area:</td>
                <td>@sqr.Area</td>
            </tr>
        </table>
    </div>
  2. In the Solution Explorer, aexpand Pages, expand Shared, and double-click _Layout.cshtml
  3. Change the _Layout.cshtml document as follows:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Geometry</title>
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
        <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/Geometry.css" asp-append-version="true" />
    </head>
    <body>
        <header>
            <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
                <div class="container">
                    <a class="navbar-brand" asp-area="" asp-page="/Index">Geometry</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/SquareSummary">Square</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/Ellipse">Ellipse</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </header>
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>
    
        <footer class="border-top footer text-muted">
            <div class="container">
                <p class="text-center common-font">&copy; 2022 - Geometry - <a asp-area="" asp-page="/Privacy">Privacy</a></p>
                
            </div>
        </footer>
    
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    
        @await RenderSectionAsync("Scripts", required: false)
    </body>
    </html>
  4. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging
  5. Click the Square link

    Accessing a Property Reader

  6. In the Side text box, type 148.97
  7. Click the Calculate button

    Accessing a Property Reader

  8. Return to your programming environment
  9. To create a new class, in the Solution Explorer, click Models -> Add -> Class...
  10. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the file Name to Ellipse
  11. Click Add
  12. In the document, type:
    namespace Geometry2.Models
    {
        public class Ellipse
        {
            private double _rad_, _Rad_;
    
            public double CalculateArea()
            {
                return _Rad_ * _rad_ * 3.14159265;
            }
        }
    }

An Expression-Bodied Property

We have learned to get a get clause of a property with a simple return value. Here is an example:

@functions{
    class Season
    {
        int temp;

        public int MeanTemperature
        {
            get
            {
                return temp;
            }
        }
    }
}

If you have a get clause that uses a simple return value, the C# language provides a simple way to implement such a clause. To do that, remove the curly brackets. Replace the return keyword with the => operator. Here is an example:

@functions{
    class Season
    {
        int temp;

        public int MeanTemperature
        {
            get => temp;
        }
    }
}

Using the Body of a Property Reader

The body of a get clause of a property can be as complicated as you want, instead of simply returning its associated field. For example, you can declare a variable in the clause. You can decide to use such a variable or not. For example, you can involve such a variable in an expression. Here is an example:

@functions{
    public class Mattress
    {
        int _thk;

        public string Thickness
        {
            get
            {
                string pds = "pounds";

                return _thk + " " + pds;
 	    }
        }
    }
}

Introduction to Property Writers

Introduction

Instead of retrieving the value of a field of a class, you may want external classes to be able to change the value of that member. A property is referred to as write if it can change (or write) the value of its corresponding field.

To create a write property, in the body of the property, type a contextual keyword named set. Create a body, which is delimited by curly brackets, for the property. Here is an example:

public class TimeSheet
{
    public double Monday
    {
    	set {}
    }
}

Once again, to make your code easy to ready, you can write each curly bracket on its own line. Here is an example:

public class TimeSheet
{
    public double Monday
    {
    	set
	{
	}
    }
}

A Value for a Property Writer

A write property is used to pass a value from outside the class to a field of its class. Therefore, the least operation you can perform with a write property is to assign it a value that would be provided by the outside world. To support this, C# provides a contextual keyword named value. Assign this keyword to the set keyword. This can be done follows:

public class TimeSheet
{
    private double _mon;

    public double Monday
    {
    	set
        {
    	    _mon = value;
        }
    }
}

In the same way, you can create as many write properties as you need.

Practical LearningPractical Learning: Creating Property Writers

  1. Change the class as follows:
    namespace Geometry2.Models
    {
        public class Ellipse
        {
            private double _rad_, _Rad_;
    
            public double radius
            {
                set
                {
                    _rad_ = value;
                }
            }
    
            public double Radius
            {
                set
                {
                    _Rad_ = value;
                }
            }
    
            public double CalculateArea()
            {
                return _Rad_ * _rad_ * 3.14159265;
    	}
        }
    }
  2. In the Solution Explorer, right-click Pages -> Add -> Razor Page...
  3. In the Add New Scaffoled Item dialog box, make sure Razor Page - Empty is selected.
    Click Add
  4. Type Ellipse as the name of the class

Accessing a Property Writer?

To access a property writer, you must first declare a variable of its class and use the period operator. Like its name indicates, a property writer is used only to receive a value. This means that you can assign a value to a property writer, but, unlike a property reader, you can get the value of a property writer.

Practical LearningPractical Learning: Using a Property Writer

  1. Change the Ellipse.cshtml as follows:
    @page
    @model Geometry2.Pages.EllipseModel
    @using Geometry2.Models
    @{
        double small = 0.00;
        double large = 0.00;
        Ellipse els = new Ellipse();
    
        if (Request.HasFormContentType)
        {
            small = double.Parse(Request.Form["txtSmallRadius"]);
            large = double.Parse(Request.Form["txtLargeRadius"]);
            
            els.radius = small;
            els.Radius = large;
        }
    }
    
    <h1 class="text-center common-font">Geometry - Ellipse</h1>
    <hr />
    <p class="text-center"><img src="../images/Ellipse1.png" width="619" height="378" /></p>
    <hr />
    <div class="delimiter common-font">
        <form name="frmGeometry" method="post">    
            <table class="table">
                <tr>            
                    <td width="125"><label for="txtSmallRadius">Small Radius:</label></td>
                    <td><input type="text" name="txtSmallRadius" value=@small class="form-control" /></td>
                </tr>
                <tr>            
                    <td width="125"><label for="txtLargeRadius">Large Radius:</label></td>
                    <td><input type="text" name="txtLargeRadius" value=@large class="form-control" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td class="text-center"><input type="submit" value="Calculate" class="btn-primary" /></td>
                </tr>
            </table>
        </form>
        
        <h1 class="text-center common-font">Ellipse Summary</h1>
        
        <table class="table">
            <tr>
                <td width="125">Area:</td>
                <td>@els.CalculateArea()</td>
            </tr>
        </table>
    </div>
  2. To execute, on the main menu, click Debug -> Start Without Debugging
  3. If the browser presents a Resend button, click that button or refresh the browser
  4. Click the Ellipse link

    Accessing a Property Reader

  5. In the Small Radius text box, type 167.97
  6. In the Large Radius text box, type 338.48
  7. Click the Calculate button

    Accessing a Property Reader

  8. Return to your programming environment
  9. Click the Square.cs tab to access its class

An Expression-Bodied Property Writer

A property writer is usually the best place to validate, to accept, or to reject a value that a property must deal with. This means that sometimes you will use to set clause to process a value. Still, many times, that clause will include only a single-line expression. In that case, you can omit the body of the clause. After the set keyword, type => and the expression that assigns value to the private field of the property. Here is an example:

public class Employee
{
    private string code;

    public string ContractIdentifier
    {
        set => code = value;
    }
}

Introduction to Read/Write Properties

Introduction

In the above sections, we created properties with either get or set clauses. A property that has only a get clause is referred to as a read-only property. A property that has only a set clause is referred to as a write-only property.

Creating a Read/Write Property

A property is referred to as read/write if it can both receive values from the outside world and can provide values to the outside world. Therefore, a read/write property has both a get and a set sections.

To create a read/write property, you can/should first create a private field in the body of the class. Then create a get and a set clauses in the body of the property. In the body of the get section, return the field. In the body of the set section, assign the contextual value keyword to the field. Here is an example:

public class Square
{
    double s;

    public double Side
    {
        get
        {
            return s;
        }

        set
        {
            s = value;
        }
    }
}

By tradition, the get section is created before the set section, but that is not a rule. You can as well create a set section before a get section.

If you are using Microsoft Visual Studio, to generate a read/write property, right-click the section where you want to create the property and click Insert Snippet... Double-click Visual C#. In the list, double-click propfull:

Property Full

Practical LearningPractical Learning: Creating Read-Write Properties

Introduction to Initializing a Read-Write Property

There are various ways you can make sure that a property would get its values. We already saw that one way is to create an accessory method in the class, add a parameter of the type of the property and, in the body of the method, assign the argument to the property's field. Another way is to create a read/write property and stop there; then simply eventually let clients of the class assign a value to the property. Here is an example:

Employee empl = new Employee();

empl.ContractIdentifier = "HL-9480";

public class Employee
{
    private string code;

    public string ContractIdentifier
    {
        get { return code;  }
        set { code = value; }
    }
}

Practical LearningPractical Learning: Initializing a Read-Write Property

  1. Click the Square.cshtml tab to access the razor page
  2. Change the document as follows:
    @page
    @model Geometry2.Pages.SquareModel
    @using Geometry2.Models
    @{
        Square sqr = new Square();
    
        if (Request.HasFormContentType)
        {
            double length = double.Parse(Request.Form["txtSide"]);
    
            sqr.Side = length;
        }
    }
    
    <h1 class="text-center common-font">Geometry - Square</h1>
    <hr />
    <p class="text-center"><img src="../images/Square1.png" width="414" height="492" /></p>
    <hr />
    <div class="delimiter common-font">
        <form name="frmGeometry" method="post">    
            <table class="table">
                <tr>            
                    <td width="125"><label for="txtSide">Side:</label></td>
                    <td><input type="text" id="txtSide" name="txtSide" value=@sqr.Side class="form-control" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td class="text-center"><input type="submit" value="Calculate" class="btn-primary" /></td>
                </tr>
            </table>
        </form>
        
        <h1 class="text-center common-font">Square Summary</h1>
        
        <table class="table">
            <tr>
                <td width="125">Perimeter:</td>
                <td>@sqr.Perimeter</td>
            </tr>
            <tr>
                <td>Area:</td>
                <td>@sqr.Area</td>
            </tr>
        </table>
    </div>
  3. To execute the program, on the main menu, click Debug -> Start Without Debugging
  4. If the browser presents a Resend button, click it or refresh the browser
  5. Click the Square link
  6. Click the Side text box and type 1397.77
  7. Click the Calculate button

    Accessing a Property Reader

  8. Return to your programming environment

An Expression-Bodied Property

To simplify the code of a read/write property, you can create an expression-body for each. To do that, type the contextual keyword of the clause, followed by the => operator. For the get clause, add the field of the property. For the set clause, assign the contextual value keyword to the field of the property. Here is an example of a read/write property with expression bodies:

public class Employee
{
    private string code;

    public string ContractIdentifier
    {
        get => code;

        set => code = value;
    }
}

Practical LearningPractical Learning: Creating Expression-Bodied Properties

  1. Change the Square class as follows:
    namespace Geometry2.Models
    {
        public class Square
        {
            private double s;
    
            public double Side
            {
                set => s = value;
                get => s;
            }
    
            public double Perimeter
            {
                get => s * 4;
            }
    
            public double Area
            {
                get => s * s;
    	}
        }
    }
  2. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging
  3. Click the button on the browser or refresh the browser
  4. Change the Side value to 326.83
  5. Click the Calculate button

    Accessing a Property Reader

  6. Close the browser and return to your programming environment
  7. Close your programming environment

Previous Copyright © 2001-2022, C# Key Tuesday 16 November 2021 Next