The so-called new syntax 2 in. NET: Anonymous class, anonymous method and extension method,. net Anonymous

Source: Internet
Author: User
Tags reflector

The so-called new syntax 2 in. NET: Anonymous class, anonymous method and extension method,. net Anonymous

Opening part: in the previous article, we learned about the so-called new syntax, such as automatic attributes, implicit types, and automatic initializes. This article continues, look at anonymous classes, anonymous methods, and common extension methods. Although they are common things, we may not all understand the mysteries of them. Therefore, follow the pace of this article to continue watching.

/* 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 1. Anonymous class 1.1. Sorry, I am sorry. during development, we sometimes declare an anonymous class like the following code: As you can see, in the syntax of the anonymous class, there is no name for it, but a new {} is done directly. From the external point of view, we cannot know what this class is for or what it does. Copy the code var annoyCla1 = new {ID = 10010, Name = "EdisonChou", Age = 25}; Console. writeLine ("ID: {0}-Name: {1}-Age: {2}", annoyCla1.ID, annoyCla1.Name, annoyCla1.Age); the copied code is debugged and run, we found that the Anonymous class can fully implement the named class effect: 1.2 after going deep into the Anonymous class, since we found that the Anonymous class can fully implement the named class effect, then we can boldly guess that the compiler will certainly generate a class similar to the name class internally, so we still use the decompilation tool to explore it. Through Reflector decompilation, we found the Anonymous class generated by the compiler, as shown in: (1) After an anonymous class is compiled, a [generic class] is generated. <> f _ AnonymousType0 <ID> j _ TPar, <Name> j _ TPar, and <Age> j _ TPar> are generic classes; (2) The attributes generated by the Anonymous class are read-only, and the corresponding fields are read-only. Therefore, if we assign values to the attributes in the program, an error will occur; (3) it can be seen that the Anonymous class also overrides three methods of the base class: Equals, GetHashCode and ToString; let's take a look at how the ToString method we generated is implemented: the implementation effect is as follows: 1.3 sharing of anonymous classes can be imagined, if many anonymous classes are defined in our code, will the compiler generate a generic class for each Anonymous class? The answer is no. the compiler takes a long consideration and avoids repeated Type generation. In other words, if multiple anonymous classes are defined, a generic class can be shared if certain conditions are met. Next, let's take a look at the several situations: (1) if the defined Anonymous class is exactly the same as the one previously defined: the attribute type and order are consistent, by default, the previous generic copy code var annoyCla1 = new {ID = 10010, Name = "EdisonChou", Age = 25} is shared. Console. writeLine ("ID: {0}-Name: {1}-Age: {2}", annoyCla1.ID, annoyCla1.Name, annoyCla1.Age); Console. writeLine (annoyCla1.ToString (); // 02. the attribute type and sequence are consistent with annoyCla1, so an anonymous class var annoyCla2 = new {ID = 10086, Name = "WncudChou", Age = 25} is used together. Console. writeLine ("ID: {0}-Nam E: {1}-Age: {2} ", annoyCla1.ID, annoyCla1.Name, annoyCla1.Age); Console. writeLine ("Is The Same Class of 1 and 2: {0}", annoyCla1.GetType () = annoyCla2.GetType (); copy The Code through The last two lines in The above Code: can we determine whether it is a type? The answer is: True (2) if the attribute name and sequence are the same but the attribute type is different, a generic class is used together, but the generic parameter is changed, therefore, different classes are generated during the runtime: copy the code var annoyCla3 = new {ID = "EdisonChou", Name = 10010, Age = 25}; Console. writeLine ("ID: {0}-Name: {1}-Age: {2}", annoyCla3.ID, annoyCla3.Name, annoyCla3.Age); Console. writeLine ("Is The Same Class of 2 and 3: {0}", annoyCla3.GetType () = annoyCla2.GetType ()); we just mentioned that although the same generic class is shared, the generic parameters are changed, so different classes are generated at runtime. Therefore, we can guess that the result displayed in the last two lines of code should be False. Although they all use a generic class, they generate two different classes at runtime. (3) If the data type Name and type are the same but in different order, the compiler will recreate an anonymous class copy code var annoyCla4 = new {Name = "EdisonChou", ID = 10010, age = 25}; Console. writeLine ("ID: {0}-Name: {1}-Age: {2}", annoyCla4.ID, annoyCla4.Name, annoyCla4.Age); Console. writeLine ("Is The Same Class of 2 and 4: {0}", annoyCla4.GetType () = annoyCla2.GetType (); copy The code to run and judge The result as: False through Reflector, it can be found that the compiler indeed re-generates a generic class: 2. The anonymous method 2.1 is introduced in C #2.0 from the declaration of the delegate, it ends C #2.0 The only way to delegate a previous version declaration is to use the naming method. However, let's take a look at how we declare the delegate before there is no anonymous method. (1) first define a delegate type: public delegate void DelegateTest (string testName); (2) Compile a naming method that complies with the delegate rules: public void TestFunc (string name) {Console. writeLine ("Hello, {0}", name) ;}( 3) declare a delegate instance: DelegateTest dgTest = new DelegateTest (TestFunc); dgTest ("Edison Chou "); (4) The following output can be obtained after debugging: from the preceding steps, we can see that we want to declare a delegated instance to compile a naming method that complies with the requirements. However, if the method in the program is only used by this delegate, it will always feel a waste of code structure. As a result, Microsoft introduced an anonymous method. Using an anonymous method to declare a delegate will make the code structure concise and save some instantiation overhead. 2.2 introduce the anonymous method (1). First, let's take a look at how the above example uses the anonymous method to implement: DelegateTest dgTest2 = new DelegateTest (delegate (string name) {Console. writeLine ("Good, {0}", name) ;}); from the running result graph, we can see that we directly passed a method where the method name was originally required to be passed, this method is written in the format of delegate (parameter) {method body}. The content of the method body is directly written in. As a result, we were excited and could simplify some work! (2) second, we will use Reflector to decompile the generated program to see how the anonymous method can help us achieve the effect of the naming method. ① We can see that in the compiled classes, apart from our own defined methods, there are two more inexplicable members: ② after one-by-one viewing, the original compiler helped us generate a private delegate object and a private static method. We can make a bold guess: the original anonymous method is not a method without a name, or a method with a name is generated, but the name of this method is hidden, the method name is generated by the compiler. ③ After the above analysis, we still don't know much about it. How does the anonymous method delegate object reflect in the program? Here, we need to check the Main method, but through the C # code we did not find a little help for us to understand. At this time, it is a bit difficult for us to figure out the root cause. Fortunately, we know that we can use IL (intermediate code) to analyze it. Therefore, switch the presentation language in Reflector and change C # To IL, and you will see another world. (3) from the above analysis, we can conclude that the compiler has done two things for anonymous methods. One is to generate a Private Static delegate object and a private static method; the second is to save the generated method address to the delegate, and call the Invoke method of the delegate object at runtime to execute the method held by the delegate object. Therefore, we can also see that the anonymous method must be used in combination with the delegate. 2.3 Anonymous method extension (1) anonymous method syntax sugar-simplifies your code in development, we often use syntactic sugar to write anonymous methods, as shown below: delegateTest dgTest3 = delegate (string name) {Console. writeLine ("Goodbye, {0}", name) ;}; dgTest3 ("Edison Chou"); you can see that the new DelegateTest () is also removed using the syntax sugar. Obviously, the compiler makes us more and more relaxed. (2) passing parameters is also learned-passing an anonymous method to the method as a parameter ① during development, we often declare a method whose parameter is a delegate object, you can accept any methods that conform to the definition of the delegate. Static void InvokeMethod (DelegateTest dg) {dg ("Edison Chou");} ② we can pass the defined method address as a parameter to the InvokeMethod method, for example, InvokeMethod (TestFunc ); of course, you can also use the anonymous method. You can call the InvokeMethod method without being defined separately. InvokeMethod (delegate (string name) {Console. writeLine ("Fuck, {0}", name) ;}); (3) omitted or omitted-omitted "braces" are continuously optimized by the compiler, we found that the () behind the delegate can be omitted. Let's take a look at the following code: InvokeMethod (delegate {Console. writeLine ("I love C sharp! ") ;}), And our previous definition is as follows: public delegate void DelegateTest (string testName); static void InvokeMethod (DelegateTest dg) {dg ("Edison Chou");} we found that when defining a method, we needed to pass a string-type parameter, but we ignored the brackets after deletegate and there was no parameter, so what is the result? After debugging, the output result is: I love C sharp! At this moment, we are a bit puzzled! Clearly there are no defined parameters. Why do they still meet the parameter conditions defined by the delegate? So let's take a look at the problem with Reflector. ① In the Main function, we can see that the compiler automatically adds the method parameter that complies with the delegate definition of DelegateTest, that is, a string type string. Although I love C sharp is output, it does conform to the method definition because it accepts a string-type parameter, although this parameter is not used in the method body. ② I just saw the anonymous method in the Main function. Now let's look at the naming method that the compiler generates for us. 3. Expansion Method 3.1 magic-Expansion Method for beginners (1) I think most of the park friends are familiar with the expansion method. But let's take a look at the definition of MSDN: MSDN says: extension methods enable you to "add" methods to existing types, instead of creating a new derived type, re-compiling, or modifying the original type in other ways. The reason why "add" is quoted is that it does not add a method to the specified type. So sometimes we will ask: why is there an extension method? Here, we can think about expansion, as the name implies, it must involve scalability. In the abstract factory mode, we can switch to a new factory by adding a factory class without changing the source code. This is also the case here. without modifying the source code, adding a new method to a class will implement class extension. (2) let's look at how C # determines the extension method. through smart prompts, we find that some methods contain an arrow pointing to the bottom, check "tip" and we know that it is an extension method. The result is that the Where () method we used to filter the set is actually an extension method rather than a native method. Let's take a look at the code example using the Where extension method: copy the code static void UseExtensionMethod () {List <Person> personList = new List <Person> () {new Person () {ID = 1, Name = "Big Yellow", Age = 10}, new Person () {ID = 2, Name = "Little White", Age = 15 }, new Person () {ID = 3, Name = "Middle Blue", Age = 7 }}; // The Extension Method of IEnumerable is used below: Where var datas = personList. where (delegate (Person p) {return p. age >=10 ;}); foreach (var data in datas) {Console. writ ELine ("{0}-{1}-{2}", data. ID, data. name, data. age) ;}} copy the code. The above Code uses the Where extension method to find the data in the set Age> = 10 to form a new dataset and output it: (3) since the extension method is to expand the class, can we customize the extension? The answer is yes. Let's first take a look at how the extension method is defined. We can use the Where method definition in the IEnumerable interface to see which rules exist: by converting to the definition method, we can see in System. A static class named Enumerable in the Linq namespace, whose member methods are all static methods, and most of the first parameters of each method start with this. As a result, we can conclude that the three elements of the extension method are static class, static method, and this keyword. Public static class Enumerable {public static IEnumerable <TSource> Union <TSource> (this IEnumerable <TSource> first, IEnumerable <TSource> second, IEqualityComparer <TSource> comparer );} then the question comes again: Why must it be static? We all know that the static method does not belong to an instance of a class. That is to say, we can access this static method without instantiating this class. So, you know. (4) After reading the three elements of the extension method, we will hand over an extension method: copy the code public static class PersonExtension {public static string FormatOutput (this Person p) {return string. format ("ID: {0}, Name: {1}, Age: {2}", p. ID, p. name, p. age) ;}} copy the code above the extension method to complete a String Structure for formatting and outputting the property information of the Person object, which can complete the output effect in the above example. Therefore, we can change the above Code to the following method for output: copy the code static void UseMyExtensionMethod () {List <Person> personList = new List <Person> () {new Person () {ID = 1, Name = "Big Yellow", Age = 10}, new Person () {ID = 2, Name = "Little White ", age = 15}, new Person () {ID = 3, Name = "Middle Blue", Age = 7 }}; var datas = personList. where (delegate (Person p) {return p. age >=10 ;}); foreach (var data in datas) {Console. writeLine (data. formatOutput ());}}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.