Behind the Scenes Look at C#: Properties - The Private Fields Example
(Page 2 of 4 )
The following application contains the updated version of the class Worker, which defines the get and set methods and modifies the the fields to be private, not public. The code contains a new C# keyword called throw, which is used to throw a new exception object. I will talk about exceptions in this series; I know that many of you know about them. Anyway, for those of you who don't know what an exception is, think of it as a new way to say "I have some error with my code and it needs to be handled." Copy the following code and run it:
using System;
namespace Properties
{
class Class1
{
static void Main(string[] args)
{
try
{
Worker worker1 = new Worker();
Console.WriteLine("Enter Your First Name");
worker1.SetFirstName(Console.ReadLine());
Console.WriteLine("Enter Your Last Name");
worker1.SetLastName(Console.ReadLine());
Console.WriteLine("Enter Your Department");
worker1.SetDepartment(Console.ReadLine());
Console.WriteLine("Enter Your Age");
worker1.SetAge(Convert.ToInt32(Console.ReadLine()));
Console.WriteLine(worker1);
Console.ReadLine();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
}
public class Worker
{
private string firstName;
private string lastName;
private string department;
private int age;
// writing the get methods
public string GetFirstName()
{
return this.firstName;
}
public string GetLastName()
{
return this.lastName;
}
public string GetDepartment()
{
return this.department;
}
public int GetAge()
{
return this.age;
}
// writing the set methods
public void SetFirstName(string firstName)
{
if(firstName == String.Empty)
{
throw new ArgumentNullException();
}
else
{
this.firstName = firstName;
}
}
public void SetLastName(string lastName)
{
if(lastName == String.Empty)
{
throw new ArgumentNullException();
}
else
{
this.lastName = lastName;
}
}
public void SetDepartment(string dept)
{
switch(dept)
{
case "IT":
this.department = "IT";
break;
case "HR":
this.department = "HR";
break;
case "Sales":
this.department = "Sales";
break;
default:
throw new ArgumentException("invalid department");
}
}
public void SetAge(int age)
{
if(age > 18 && age < 40)
{
this.age = age;
}
else
{
throw new ArgumentException("The worker can't be over 40");
}
}
public override string ToString()
{
return firstName +" "+lastName+" is working in "+department+
" and he's "+age+" years old";
}
}
}
Enter whatever values you like for the first name, last name and department, but enter 1000 for the age and see what will happen.

The object has not been created, and the application has printed to the console window "The worker can't be over 40", which is our business rule for this example. The Worker class has been modified. The fields are now private instead of public, so the client code has no access or visibility to these fields. Take a look at the IntelliSense feature of VS.NET when we try to access worker1 object members:

You don't see the private fields and you don't have direct access to them. You set and get their values through the Getxxx methods and Setxxx methods you see in the list. The syntax of the Get methods is very simple: you declare the method public and define the return data type as the same as the field. The Set methods can be as complex as you want, because you may validate data and do other operations, such as throw an exception in case the data is invalid.
We have done this in the example. In the method SetFirstName we wrote code to test on the assigned value. If it's equal to String.Empty (that means that it doesn't contain any characters), an exception of type ArgumentNullException will be thrown. Try it yourself. Press the Enter key without typing any characters to the First Name and the application will print to the Console Window "value can't be null". The same code works for the SetLastName method.
The SetDepartment method uses a switch case statement to assign the value of the worker department. In case of an invalid department entry, the default section will be executed, which will throw the exception ArgumentException. The SetAge method tests that the value assigned is greater than 18 and less than 40. If it's not, the else block executes, which throws the exception ArgumentException too.
As you can see, we have control over the values that will be assigned to the private fields. We throw exceptions to stop the object creation process. Actually the code is more complex than our example when you use database, ADO.NET and Windows Forms.
The Main method creates an object of type Worker and gets the values from the user. Note that we are not using the assignment operator as with the public fields example to assign the values to the fields, but we are passing the values (that return from the method Console.ReadLine()) as method arguments. All of the statements are enclosed in a try/catch block, which will be discussed in detail with exceptions. For now think of the try block as a block of statements that can throw an exception, and the catch block as containing code to catch and handle the exception. In the Catch block we simply write the exception.Message (the message error) and wait for the user to press the Enter key using the Console.ReadLine() method.
This code is fine and does exactly what we need, but as you can see there are some differences between using fields and methods that handle fields. For example, we can't use the assignment operator with the get/set methods like we do with the fields. The redundant methods declaration to get and set the values of the fields also makes the code look ugly. We need a way to simulate the field behavior while we still use the power of methods we have seen, and C# features a construction called property to solve our problem. Let's meet our new class member.
Next: C# Properties >>
More C# Articles
More By Michael Youssef