No need for the reflector, the shared source code distrbutions.... we will see the original source code files and the comments into the next release of Microsoft .NET Framework 3.5 and VS 2008
For more information find below the following link:
http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx
Interview with Shawn Burke on Microsoft .NET Source Code Release: http://www.hanselminutes.com/default.aspx?showid=101
Enjoy it..
Cheers,
In the last post I talked about the Automatically Implemented Properties which is very cool productivity feature, and I talked a little bit about the underlying auto generated backing fields, since the post, I tried to play with the auto generated fields to find out a way to write the backing field name in the C# directly, the backing field looks like:
The <Name> syntax is not allowed to be used with the C# identifiers, C# 3.0 compiler architects go with this in order not to conflict with any other fields written by the developer.
Now what about the serialization, let's say that I want to add some rules and validation to the getter and setter after implementing it, what will happen to the pre-serialized files after modifying the properties to the old pattern?
When using XML/SOAP serialization we don’t have to think a lot about the effects of the new change, but if we are using the Binary serialization then I think we are in a big troubleL!!!
The main difference between the XML and the Binary serialization is that the Binary serialization creates a byte for byte copy of the object's memory image and persist it to the disk which means that the serialized data contains all the members of the object, no matter if they are private or public in addition to the CLR types and the versioning information…which is our problem.
Here's an example serializable class that I will use it to demonstrate this case:
|
namespace Properties.AutoImplemented
{
[Serializable]
public class JordevMember
{
//Read Only Property
public string Name { get; set; }
//Write Only Property
public string Job { get; set; }
public string Email { get; set; }
public DateTime DateOfBirth { get; set; }
}
} |
|
Here's a trivial implementation of the serialization and deserialization process using the classes included in the Framework:
|
/// <summary>
/// This method serialize instance of JordevMember with sample data...
/// </summary>
public static void SerializeJordevMember()
{
//Definning instance of JordevMember class...
JordevMember jdvMember = new JordevMember();
//Filling JordevMember instance with sample data...
jdvMember.Name = "Ammar";
jdvMember.Job = "Software Engineer";
jdvMember.Email = "Ammar@jordev.net";
FileStream fs = new FileStream(@"c:\JordevMemberData.bin", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
try
{
//Serializing binary image of the JordevMember object
bf.Serialize(fs,jdvMember);
}
catch (SerializationException ex)
{
Console.WriteLine("Serialization Failed because: " + ex.Message);
}
finally
{
fs.Close();
}
}
/// <summary>
/// This method Deserialize the presisited instance of JordevMember class...
/// </summary>
public static void DeserializeJordevMember()
{
//Definning instance of JordevMember class...
JordevMember jdvMember = new JordevMember();
FileStream fs = new FileStream(@"c:\JordevMemberData.bin", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
try
{
//Deserializing binary image of the JordevMember object
jdvMember = (JordevMember)bf.Deserialize(fs);
Console.WriteLine("Jordev Member Name : " + jdvMember.Name);
Console.WriteLine("Jordev Member Job : " + jdvMember.Job);
Console.WriteLine("Jordev Member Email : " + jdvMember.Email);
}
catch (SerializationException ex)
{
Console.WriteLine("Deserialization Failed because: " + ex.Message);
}
finally
{
fs.Close();
}
} |
And now let's take a look to the JordevMemberData.bin contents:
|
☺ ☺ ♀☻ PAutoImplementedProperties, Version=1.0.0.0, Cul
ture=neutral, PublicKeyToken=null♣☺ 'Properties.AutoImplemented.Jord
evMember♦ §<Name>k__BackingField¶<Job>k__BackingField▬<Email>k__Back
ingField∟<DateOfBirth>k__BackingField☺☺☺ ♪☻ ♠♥ ♣Ammar♠♦ ◄Softwar
e Engineer♠♣ ►Ammar@jordev.net ♂ |
As I mentioned before the binary serialization persist all the private and public members of the object, we can notice here the underlying auto generated backing fields names into the content of the deserialized file.
Here's below the JordevMember class with the old pattern of implementing the properties:
|
/// <summary>
/// This is the classical class of JordevMember using trivial way of implementing properties.
/// </summary>
public class JordevMember
{
private string _name;
private string _job;
private string _email;
private DateTime _dateofbirth;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public string Job
{
get
{
return _job;
}
set
{
_job = value;
}
}
public string Email
{
get
{
return _email;
}
set
{
_email = value;
}
}
public DateTime DateOfBirth
{
get
{
return _dateofbirth;
}
set
{
_dateofbirth = value;
}
}
} |
If we try to use the classic version of properties with the Pre-Serialized files we will see no results.
As we see in the previous samples, it's not recommended to use the automatic properties when the Binary serialization is required.
Cheers,
C# 3.0 is the new version of the language includes many new features inspired by functional programming language, to not be confused the 3.0 means the version of the language specification and not the .NET Framework version.
I will talk here about the Auto implemented properties, and I want to mention here that it's not an enhancement on the language that’s reflect an enhancement on the generated intermediate language (IL); it's just a new compiler feature or we can say it’s a kind of productivity enhancement and can replace one of the code generation tools features.
It's cool to have a new quick way to add new properties without the need to write the getter and setter declarations.
Every developer has written entity or model class before, these classes which contains the trivial properties with both getter and setter for each fields.
The classic way of adding properties is like the following simple example:
|
namespace Properties.Classic
{
/// <summary>
/// This is the classical class of JordevMember using trivial way of implementing properties.
/// </summary>
public class JordevMember
{
private string _name;
private string _job;
private string _email;
private DateTime _dateofbirth;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public string Job
{
get
{
return _job;
}
set
{
_job = value;
}
}
public string Email
{
get
{
return _email;
}
set
{
_email = value;
}
}
public DateTime DateOfBirth
{
get
{
return _dateofbirth;
}
set
{
_dateofbirth = value;
}
}
}
} |
The Automatic Properties delegates the writing of the getter and setter for the private fields and generates backing fields for this target.
Below the JordevMember class implemented using the Automatic Properties:
|
namespace Properties.AutoImplemented
{
public class JordevMember
{
public string Name { get; set; }
public string Job { get; set; }
public string Email { get; set; }
public DateTime DateOfBirth { get; set; }
}
} |
Let's go internally and check out how the compiler treats the previous classes in the classic and the new version.
The easiest way to slice the properties is to disassemble it using the ILDASM utility, Here's the IL generated by the C# compiler for the getter accessor of the Name property in the classic version of Jordev Member:
And here's the generated IL of the new version of JordevMember with the automatically implemented properties: