Friday, May 23, 2008

Automatic Properties

Automatic Properties
If you are already c# developer and you are developing classes with properties as shown below.


public class Student

{

private string _firstName;
private string _lastName;
private int _age;

public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}

public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}

public int Age
{

get { return _age;}
set {_age = value;}
}

}

as mention above we are not applying any logic in the getters/setters of our properties but instead we just get/set the value directly to a field. so there is question in our mind that instead of that why not just use fields instead of properties? There are losts of downsides to exposing public fields.

Few problems are mention below.

1) You can't easily data bind against fields

2) If you expose public fields from your classes you can't later change them to properties (for example: to add validation logic to the setters) without recompiling any assemblies compiled against the old class.

The new C# compiler that ships in "Orcas" has new feature named "Automatic Properties". Automatic properties allow you to avoid having to manually declare a private field and write the get/set logic -- instead the compiler can automate creating the private field and the default get/set operations for you.

As above example I have to write just as bellow.

public class Student
{

public string FirstName { get; set; }
public string LastName { get; set; }

public int Age { get; set; }

}

When the C# "Orcas" compiler encounters an empty get/set property implementation like above, it will now automatically generate a private field for that within class, and implement a public getter and setter property implementation to it. The benefit of this is that from a type-contract perspective, the class looks exactly like it did with our first (more verbose) implementation above. This means that unlike public fields I can in the future add validation logic within my property setter implementation without having to change any external component that references my class.

Above code some what like abstract property inside the abstract class but it is different than the code mention below.

public abstaract class Student
{

public abstract string FirstName { get; set; }

}

Automatic private field generated by complier can not be viewed directly it can be seen only in the ILDASM.exe.

Limitations of Automatic Properties

1) You can not define read-only and write only properties.

// Read-only property? Error!

public int MyReadOnlyProp { get; }

// Write only property? Error!

public int MyWriteOnlyProp { set; }

Above code will give you compile time error it must have both read and write properties.

2) As mention that private backing field for the public property is generated by the compiler run time. Developer can use only the public property in his/her code. He/she can’t user private field in the code. In below example I have custom class which implements ToString() which can't use private field.

class Employee

{

public string FirstName { get; set; }
public override string ToString()
{

// No access to the private member in the defining
// class. Must use properties!
// you can not use here private filed since it is not visible here it will be
// generated by compiler

return string.Format("Employee First Name = {0}", FirstName);

}

}

Restrict Access on Automatic Properties:

As In the C# 2.0 we were able to set the access modifier to getter ans setter in automatic property it is also possible.

// Anyone can get the FirstName value, but
// only the defining type and the children can set it.

public int FirstName

{

get { return firstName; }
protected set { firstName = value; }

}

This same possibility is allowed using automatic property syntax as follows:

public string FirstName { get; protected set; }

Of course, with this update, the Main() method would now generate a compiler error when attempting to assign the value of the FirstName property:

static void Main(string[] args)

{

...
// Error! Setting the
FirstName is only possible
// from within the Employee type or by a child type!

e. FirstName = "Tejas";

// Getting the value is still OK.

Console.WriteLine("Your FirtName is {0}? ...", e.FirstName);

Console.ReadLine();

}

Regarding Automatic Properties and Default Values

When you use automatic properties to encapsulate numerical or Boolean data, you are able to use the auto generated type properties straightaway within your code base, as the hidden backing fields will be assigned a safe default value that can be used directly. However, be very aware that if you use automatic property syntax to wrap a reference type, the hidden private reference type will also be set to a default value of null:

class EmployeeCollection

{

// The hidden int backing field is set to zero!
public int NumberOfEmployee { get; set; }

// The hidden Employee backing field is set to null!
public Employee GEmployee { get; set; }

}

Given C#’s default values for field data, you would be able to print out the value of

NumberEmployee as is (as it is automatically assigned the value of zero), but if you directly invoke Employee, you will receive a null reference exception:

static void Main(string[] args)

{

...

EmployeeCollection e = new EmployeeCollection ();

// OK, prints defualt value of zero.

Console.WriteLine("Number of Employee: {0}", e.NumberOfEmployee);

// Runtime error! Backing field is currently null!

Console.WriteLine(e.GEmployee. FirstName);

Console.ReadLine();

}

Given that the private backing fields are created at compile time, you will be unable to make use of C# field initialization syntax to allocate the reference type directly with the new keyword. Therefore, this work will need to be done with type constructors to ensure the object comes to life in a safe manner. For example:

class EmployeeCollection

{

// The hidden backing field is set to zero!
public int NumberOfEmployee { get; set; }

// The hidden backing field is set to null!
public Employee GEmployee { get; set; }

// Must use constructors to override default
// values assigned to hidden backing fields.

public EmployeeCollection ()
{

GEmployee = new Employee ();
NumberOfEmployee = 1;
}

public EmployeeCollection (Employee emp, int number)

{

GEmployee = emp;
NumberOfEmployee = number;
}

}

As you most likely agree, this is a very nice extension to the C# programming language, as you can define a number of properties for a class using a streamlined syntax. Be aware of course that if you are building a property that requires additional code beyond getting and setting the underlying private field (such as data validation logic, writing to an event log, communicating with a database, etc.), you will be required to define a “normal” .NET property type by hand. C# 2008 automatic properties never do more than provide simple encapsulation for an underlying data type.

No comments: