[C #6] 5-auto attribute enhancement,
0. Directory
C #6 Add feature catalog
1. Old Version code
1 internal class Person 2 { 3 public string Name { get; private set; } 4 public int Age { get; private set; } 5 6 public Person(string name,int age) 7 { 8 Name = name; 9 Age = age;10 }11 }
Normally, the C # Attribute can help us complete the work, such as the above Code. When assigning values to attributes, we can assign values to attributes anywhere. However, there is no syntax such as field declaration and immediate initialization to simplify the setting of default values. C #6 brings us this new syntax, such as assigning values to fields and assigning values to attributes.
We also know that the C # attribute is actually a private Field automatically generated by the compiler, get_xxx and set_xxx, and a metadata. For example, after the above Code is compiled:
<Name> IL of the k _ BackingField
1 .field private string '<Name>k__BackingField'2 .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 3 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
Indicates a private field. row 2nd indicates that the field is automatically generated by the compiler. Row 3rd indicates that the field is not displayed in the Debugger window.
The IL of the get_Name method:
1 .method public hidebysig specialname instance string 2 get_Name() cil managed 3 { 4 .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 5 // Code size 7 (0x7) 6 .maxstack 8 7 IL_0000: ldarg.0 8 IL_0001: ldfld string csharp6.Person::'<Name>k__BackingField' 9 IL_0006: ret10 } // end of method Person::get_Name
This is also an automatic generation method.
The IL of the set_Name method:
1 .method private hidebysig specialname instance void 2 set_Name(string 'value') cil managed 3 { 4 .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 5 // Code size 8 (0x8) 6 .maxstack 8 7 IL_0000: ldarg.0 8 IL_0001: ldarg.1 9 IL_0002: stfld string csharp6.Person::'<Name>k__BackingField'10 IL_0007: ret11 } // end of method Person::set_Name
It is also an automatic generation method.
IL of the Name attribute:
1 .property instance string Name()2 {3 .get instance string csharp6.Person::get_Name()4 .set instance void csharp6.Person::set_Name(string)5 } // end of property Person::Name
The Name attribute is composed of a get method and a set method.
2. Auto attribute enhancement syntax
1 internal class Person 2 {3 // declare the read/write attributes and initialize the default value 4 public string Name {get; set ;}= "blackheart "; 5 6 // declare the read-only attribute and initialize the default value 7 public int Age {get ;}= 1; 8 9 // declare the read-only attribute 10 public string Note {get ;} 11 12 public Person (string note) 13 {14 // initialize the default value for the read-only attribute in the constructor 15 Note = note; 16} 17 18 private void func1 () 19 {20 // error, only 21 // Note = "123"; 22 // Age = 1; 23 // can be modified in the constructor, because set accessors 24 Name = "new name"; 25} 26}
This new syntax sets the hidden private field as a read-only field (readonly) when there is no set accesser. It only allows you to set the initial value or assign a value in the constructor when declaring the field. Look at IL:
Only the Name attribute has the set_Name method, while the Age and Note attributes do not have the set accessors, and the corresponding private field is set to "initonly", indicating that this is a read-only field.
The initialization operations of the constructor method Name {get; set ;}= "blackheart" and Age {get ;}= 1 are transferred to the instance constructor ". ctor" method.
1 .method public hidebysig specialname rtspecialname 2 instance void .ctor(string note) cil managed 3 { 4 // Code size 34 (0x22) 5 .maxstack 8 6 IL_0000: ldarg.0 7 IL_0001: ldstr "blackheart" 8 IL_0006: stfld string csharp6.Person::'<Name>k__BackingField' 9 IL_000b: ldarg.010 IL_000c: ldc.i4.111 IL_000d: stfld int32 csharp6.Person::'<Age>k__BackingField'12 IL_0012: ldarg.013 IL_0013: call instance void [mscorlib]System.Object::.ctor()14 IL_0018: nop15 IL_0019: nop16 IL_001a: ldarg.017 IL_001b: ldarg.118 IL_001c: stfld string csharp6.Person::'<Note>k__BackingField'19 IL_0021: ret20 } // end of method Person::.ctor
The code generated in the preceding syntax is the same as that in the previous syntax. It is generated as a field, the get_xxx and set_xxx methods, and the corresponding property metadata. In essence, the compiler syntax is simplified.
3. Reference
C # Auto-property enhancements