Sunday, May 13, 2012

automatic-properties-object-initializers-and-collection-initializers

http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx

http://community.bartdesmet.net/blogs/bart/archive/2007/03/03/c-3-0-automatic-properties-explained.aspx

automatic properties. Basically it allows you to write stuff like this:

public string Bar { get; set; }
which will be translated automatically in something like this:

private string foo; public string Bar { get { return foo; } set { foo = value; }
}
 
 
1 using System; 2 3 namespace ConsoleApplication1 4 { 5 class Program 6 { 7 public string Name { get; set; } 8 9 static void Main(string[] args)10 {11 var p = new Program();12 p.Name = "Bart";13 }14 }15 }
The clue is on line 7 where I've declared an automatic property. Basically this frees me from the burden of declaring a private variable and a get and set accessor to it by means of a property. Although you can just use the "prop" code snippet in Visual Studio, this is much cleaner in case you don't need the private fields at all. Imagine some entity mapping class that consists of 20 properties, do you want to see all of the private variable, getter and setter noise around your class? I don't think so.
Please notice that the use of automatic properties is not equal to just defining a public field - you still keep the get_PropertyName and set_PropertyName methods behind the scenes as well as all the metadata that goes with a property, as illustrated below:

This means your code can be upgraded at any time to define getters/setters together with an explicitly defined member variable when you need to do so, without having to recompile external consumers of your code (i.e. the "contract" remains untouched). Behind the scenes what happens is the injection of a private member variable, prefixed with <>k__AutomaticallyGeneratedPropertyField#, like this:
.field private string '<>k__AutomaticallyGeneratedPropertyField0' .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
The CompilerGeneratedAttribute attribute is useful for tools to find out about these auto-generated things. Next, the compiler emits a getter and setter for you:
.method public hidebysig specialname instance string get_Name() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 11 (0xb) .maxstack 1 .locals init (string V_0) IL_0000: ldarg.0 IL_0001: ldfld string ConsoleApplication1.Program::'<>k__AutomaticallyGeneratedPropertyField0' IL_0006: stloc.0 IL_0007: br.s IL_0009 IL_0009: ldloc.0 IL_000a: ret } // end of method Program::get_Name .method public hidebysig specialname instance void set_Name(string 'value') cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 8 (0x8) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: stfld string ConsoleApplication1.Program::'<>k__AutomaticallyGeneratedPropertyField0' IL_0007: ret } // end of method Program::set_Name
All the stuff in here is pretty much the same as a manually defined property, except for the presence of the CompilerGeneratedAttribute attribute. Finally, there's the metadata for the property:
.property instance string Name() { .get instance string ConsoleApplication1.Program::get_Name() .set instance void ConsoleApplication1.Program::set_Name(string) } // end of property Program::Name
Notice that automatic properties should have both a getter and a setter declared. Read-only or write-only properties are not permitted.

No comments:

Post a Comment