A security capsule can save your program’s life (Part.3)

So, let me show how easy it is to implement encapsulation in C#. I will start from the very old fashion to create a encapsulated field then will show the easiest way. Basically to encapsulate a field level variable we would simply declare a setter and a getter method. With the help of the setter method we would set a value for our field level variable and with the getter method we would extract the value from our field level variable set by the setter method. So open the project we have been working on so far and do the followings

Open the User class. We have four field level variables. i.e.
public string Name;
public string Email;
public string Mobile;
public bool HideMobileNo = true;

Lets make a setter and getter method for the Name variable first.

The setter and getter methods look like this

public void SetName(string name)
{
    this.Name = name;
}
public string GetName()
{
    return this.Name;
}

And also same for the rest like this

public void SetEmail(string email)
{
    this.Email = email;
}

public string GetEmail()
{
    return this.Email;
}

public void SetMobile(string mobile)
{
    this.Mobile = mobile;
}

public string GetMobile()
{
    return this.Mobile;
}

public void SetHideMobileNo(bool hideMobileNo)
{
    this.HideMobileNo = hideMobileNo;
}

public bool GetHideMobileNo()
{
    return this.HideMobileNo;
}

So what we have done here is simply removed any kind of hard coded value in the field level variable and declare a setter and a getter method for each and every fields. By doing that we have omitted the possibility of any kind of mistakes. By mistakes I mean, forget to set a value for a field level variable or getting a wrong value from the field level variable. So this is the very old fashioned way to encapsulate fields. In C# we can easily encapsulate a field with the help of Property. Means that we can declare our variables like Property in C#. We have been working with these property from the start of our project. For example, We set the Name property for one of our textBox to nameTextBox. Each property has a get and set method internally. So we don't have to go through the headache of declaring two methods for each fields. Rather we can do as followings.

private string _name;
public string _email;
public string _mobile;
public bool _hideMobileNo;

public string Name
{
    get { return _name; }
    set { _name = value; }
}
public string Email
{
    get { return _email; }
    set { _email = value; }
}
public string Mobile
{
    get { return _mobile; }
    set { _mobile = value; }
}
public bool HideMobileNo
{
    get { return _hideMobileNo; }
    set { _hideMobileNo = value; }
 }

See that each property has a get and set method internally. The set sets the value passed to property to the field variable contained in keyword value. And the get returns the value that has been just set. This kind of property is called read and write property. We can also declare logic inside set and get. For example we can remove white spaces from the Name property when user enters his/her name like this

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        _name = _name.Trim();
     }
} 

Here Trim() is a function which removes additional white spaces from string.

So read and write property is useful when there is a possibility of implementing a logic associated with a field. But most of the time additional business logic are implemented in separated class to follow the separation of concern pattern. So we can declare auto property like this

public string Name { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public bool HideMobileNo { get; set; }

So, Lets go back to our project and implement the User class like this

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
    public bool HideMobileNo { get; set; }

    public string GetMobileNo()
    {
        if (HideMobileNo == true)
        {
            return "N/A";
        }
        else
        {
            return Mobile;
        }
    }
}

Now go to the Form1.class and rewrite the code as followings

public partial class Form1 : Form
{
    private User user;
    private ListViewItem item;

    public Form1()
    {
        InitializeComponent();
        user = new User();
        user.Name = "Fiyaz";
        user.Email = "fiyazhasan@yahoo.com";
        user.Mobile = "0171-XXXXXXX";
        user.HideMobileNo = setPrivateCheckBox.Checked;

        //Tweak the listview design
        userListView.View = View.Details;
        userListView.LabelEdit = true;
        userListView.AllowColumnReorder = true;
        userListView.FullRowSelect = true;
        userListView.GridLines = true;
        userListView.Sorting = SortOrder.Ascending;

        //Creating a listview item
        item = new ListViewItem(user.Name);
        item.SubItems.Add(user.Email);
        item.SubItems.Add(user.GetMobileNo());

        //Adding the listview columns
        userListView.Columns.Add("Name", -2, HorizontalAlignment.Left);
        userListView.Columns.Add("Email", -2, HorizontalAlignment.Left);
        userListView.Columns.Add("Phone", -2, HorizontalAlignment.Left);

        //Add the items to the ListView.
        userListView.Items.AddRange(new ListViewItem[] { item });
    }

    private void ClearTextBoxes()
    {
        nameTextBox.Text = "";
        emailTextBox.Text = "";
        mobileTextBox.Text = "";
    }

    private void submitButton_Click_1(object sender, EventArgs e)
    {
        //Create a new user instance with new values
        user = new User();
        user.Name = nameTextBox.Text;
        user.Email = emailTextBox.Text;
        user.Mobile = mobileTextBox.Text;
        user.HideMobileNo = setPrivateCheckBox.Checked;

        //Create a listview item
        item = new ListViewItem(user.Name);
        item.SubItems.Add(user.Email);
        item.SubItems.Add(user.GetMobileNo());

        //Add the newly created item
        userListView.Items.AddRange(new ListViewItem[] { item });

        //Clear the text from the textbox
        ClearTextBoxes();
    }

    private void setPrivateCheckBox_CheckedChanged_1(object sender, EventArgs e)
    {
        user.HideMobileNo = setPrivateCheckBox.Checked;
    }

    private void cancelButton_Click(object sender, EventArgs e)
    {
        ClearTextBoxes();
    }
}

Now run the program it will behave as it was supposed to.

So we saw that why encapsulation is an important factor in object oriented programming and also learn how to implement encapsulation in coding. Hope you liked all three parts on OOP encapsulation. Stay geeky. I'll be back soon. :)