One of the so-called New syntaxes in. NET: Automatic attributes, implicit types, named parameters, and automatic Initiators
/* New syntax Index */1. auto-Implemented Properties2. implicit var3. default value and name parameter 4. object initializer and set initializer {} 5. anonymous class & anonymous method 6. extension Method 7. the system has built-in delegate Func/Action8.Lambda expression 9. standard Query operator Standard Query Operator10.LINQ Query expression I. Automatic attribute search before 1.1: first write private variables, then write public attributes copy code public class Student {private Int32 _ id; public Int32 Id {get {return _ id;} set {_ id = value;} private string _ name; public string Name {get {return _ name;} set {_ na Me = value ;}} private Int16 _ age; public Int16 Age {get {return _ age ;}set {_ age = value ;}} copy Code 1.2 Current Practices: declare the empty attribute public class Person {public Int32 ID {get; set;} public string Name {get; set;} public Int16 Age {get; set ;}} PS: Now, is there much less code? Directly declare an empty attribute, and the compiler can help us complete the previous private member fields and the get and set methods. Therefore, we can use the Reflector decompilation tool to look at it, how does one complete this operation. 1.3 The Great "country-based"-(C Sharp Compiler): C # Compiler PS: Why is it mentioned here? First, it is because the country-based short name is, second, I prefer to eat Chinese fast food in rural areas! (It seems like advertising to rural areas, but I still like rural areas. Aside from the price, of course.) (1) first, let's compile the above small program, then drag the compiled exe/dll to the Reflector (or ILSpy is also praised) (2) Find the Person class and you can see the compiled result: automatically generates private fields corresponding to the common attributes. We can see that the automatically generated fields are different from the previous fields: ① A [CompilerGenerated] Attribute is added to the top of each field. As the name suggests, it indicates that it is generated by the compiler. ② the variable names of each field are in a certain format, for example, the format of <Age> k _ BackingField is as follows: <attribute name> k_BackingField; (BackingField is the field behind it as the name suggests) (3) the automatically generated field is read, let's take a look at how the attribute is defined: ① like the automatically generated field, the attribute also adds the [CompilerGen Erated] features to show differences ② As we all know, attributes are the encapsulation of Two Methods of a get and a set. So how did we compile and generate the empty get/set method we wrote before, we can see that the [CompilerGenerated] feature is added in the get and set methods to show the difference. In addition, it also helps us automatically correspond to automatically generated private fields, this is consistent with the method of manually writing private fields + common attributes. Therefore, automatic attribute is a practical syntactic sugar that helps us do two things: automatically generate private fields and automatically match private fields in the get/set method. Ii. implicit type-Keyword: var 2.1: you can guess who I am? In the past, we had to specify the type of each variable when defining it. However, with var, everything becomes so harmonious that we can use a var to define all types. Copy the code var age = 100; age + = 150; var name = ""; name = "edisonchou"; Console. writeLine ("age = {0}", age); Console. writeLine ("name = {0}", name); copy the code and click Debug. The Compiler automatically matches the correct type and displays it successfully, we were curious to know whether the compiler recognized the specified type, so we checked it again through the decompilation tool: we can see that, our lovely helped us to deduce the correct type, so we couldn't help but give it a 32 thumbs up! However, the variable type cannot be changed because the type has been determined at the time of declaration. For example, an error occurs when we assign a variable in the code that is different from the type at the time of definition. 2.2 best effort on the cutting edge-implicit type application scenarios in data-type business development, we will query a data set by using LINQ, the result of this LINQ query may be an object of the ObjectQuery <> or IQueryable <> type. Therefore, if the target type is unclear, we can use the var key to declare: List <UserInfo> userList = roleService. loadRoles (param); var data = from u in userList where u. isDel = 0 select u; 2.3, but "love" means restraint-implicit type use restrictions (1) declared variables are a local variable, not static or instance fields; (2) variables must be initialized at the same time of declaration. The compiler must deduce the type based on the initialization value. (3) initialization is not an anonymous function and the initialization expression cannot be null. (4) the variable is declared only once in the statement, and the type cannot be changed after the statement is declared. (See the example above) (5) the assigned data type must be a type that can be determined during compilation; 3. Copy the code static void Main (string [] args) using the default value 3.1 Method and named parameter {// 01. parameter letter with default value Funcwithdefaparpara (); // 02. omit a default parameter and call FuncWithDefaultPara (10086); Console. readKey ();} static void FuncWithDefaultPara (int id = 10010, bool gender = true) {Console. writeLine ("Id: {0}, Gender: {1}", id, gender? "Man": "Woman");} copy the code and click Debug. The result is as follows: 3.2 The method call after compilation is the same. To explore the details of the method call with the default value of the parameter, we still use the decompilation artifact to view the mystery: (1) first, let's take a look at the method with the default value parameters after compilation: You can see, in. NET Framework uses a lot of Attribute-based development methods. Here we add the DefaultParameterValue feature to the parameter to indicate the default value. (2) Next, let's take a look at how the calling process in the Main function is compiled: we can see that the compiler helps us fill in the default values in the brackets of the method call. Here, we can't help wondering, if you do not specify the ID in the call (that is, use the default ID 10010), but only specify the Gender as false, can it be compiled? Let's try: copy the code static void Main (string [] args) {// 01. function FuncWithDefaultPara (); // 02. omitting a default parameter to call FuncWithDefaultPara (10086); // call FuncWithDefaultPara (false); Console. when ReadKey ();} copies the code, the following error occurs: We know that is not so intelligent and cannot understand our profound "intention ". There is a way to solve this need, so the name parameter is blank. 3.3 Use named parameters to introduce named parameters for method calls in the new syntax. Format: Parameter Name: parameter value copy code static void Main (string [] args) {// 01. function FuncWithDefaultPara (); // 02. omitting a default parameter to call FuncWithDefaultPara (10086); // the following error occurs: // funcwithdefaparpara (false); // 03. call FuncWithDefaultPara (gender: false); Console. readKey () ;}after the code is copied and debugged, the following results can be obtained: Through the previous analysis, we can analyze whether the call of the specified parameter value will still be generated after the name parameter is compiled: iv. Automatic initializer 4.1 attribute initiator (1) during development, we often set these attributes for new objects: static void In ItialPropertyFunc () {Person p = new Person () {Name = "Xiaoqiang", Age = 18}; Console. writeLine ("Name: {0}-Age: {1}", p. name, p. age) ;}( 2) However, after compilation, we found that the original method was the previous one: First new, and then assign a value to an attribute. Here, the compiler first generates a temporary object g_initLocal0, then assigns a value to its attribute, and finally passes the address of the g_initLocal0 object to the object p to be used. 4.2 set initializer (1) during development, we often initialize a set in instantiation: copy the code static void InitialCollectionFunc () {List <Person> personList = new List <Person> () {new Person () {Name = "Xiaoqiang", Age = 10}, new Person () {Name = "Xiao Wang", Age = 15}, new Person () {Name = "Xiao Li", Age = 18 }}; foreach (Person person in personList) {Console. writeLine ("Name: {0}-Age: {1}", person. name, person. age );}}