C # Extension Method

Source: Internet
Author: User
Tags mscorlib

C # Extension Method
C # extension method when we want to add a method to an existing type, there are two ways: first, directly add a method to the existing type; however, in many cases, the existing types are not allowed to be modified. You can use the second method to create a subclass based on the existing type and add the desired method to the subclass. When a static class occurs in C #2.0, we can also create a static tool class to implement the method to be added. In this way, you can avoid creating child classes, but the time code is not that intuitive. In fact, the above methods are not a good solution. The extension method appears in C #3.0. By using the extension method, we can directly "add" the method on an existing type. When using the extension method, you can call the Extension Method in the same way as calling the instance method. The creation and use of extension methods are relatively simple. Declaring an extension method has its own characteristics compared to a common method. Let's take a look at how to declare an extension method: it must be in a non-nested, non-generic static class (so the extension method must be a static method) it requires at least one parameter. The first parameter must contain the this keyword as the prefix. The first parameter type is also called extended type ), indicates that this method can extend this type. The first parameter cannot use any other modifier (such as out or ref). The first parameter type cannot be a pointer type according to the above requirements, we added an extension method to the int type to determine whether an int value is even: namespace ExtentionMethodTest {public static class ExtentionMethods {public static bool IsEven (this int num) {return num % 2 = 0 ;}} class Program {static void Ma In (string [] args) {int num = 10; // call the extension method Console. WriteLine ("Is {0} a even number? {1} ", num, num. IsEven (); num = 11; // directly call the extension method Console. WriteLine (" Is {0} a even number? {1} ", num, num. IsEven (); // call the static method Console. WriteLine (" Is {0} a even number? {1} ", num, ExtentionMethods. IsEven (num); Console. Read () ;}} although this example is very simple, it demonstrates the use of the extension method. The above example shows that when calling an extension method, it can be the same as calling an instance method. This is one of the reasons for using the extension method. We can add a method for an existing type. Since the extension method is a static class method, we can also call this method through static classes. Through IL, we can see that the extension method is also a compiler that converts the extension method into a static method of the static class. Call IL_001f: nopIL_0020: ldc. i4.s 11IL_0022: stloc.0IL _ 0023: ldstr "Is {0} a even number? {1} "IL_0028: ldloc.0IL _ 0029: box [mscorlib] System. int32IL_002e: ldloc.0 // call the extension method IL_002f: call bool ExtentionMethodTest. extentionMethods: IsEven (int32) IL_0034: box [mscorlib] System. booleanIL_0039: call void [mscorlib] System. console: WriteLine (string, object, object) IL_003e: nopIL_003f: ldstr "Is {0} a even number? {1} "IL_0044: ldloc.0IL _ 0045: box [mscorlib] System. int32IL_004a: ldloc.0 // call the static method IL_004b: call bool ExtentionMethodTest through the static class. extentionMethods: IsEven (int32) IL_0050: box [mscorlib] System. booleanIL_0055: call void [mscorlib] System. console: WriteLine (string, object, object) IL_005a: nopIL_005b: call int32 [mscorlib] System. console: Read () IL_0060: popIL_0061: ret has an extension method. When calling an extension method, we call an instance method. However, we should look at this problem from two perspectives: through the extension method, we can make some method calls more easy to understand, and the relationship with the instance looks more harmonious. For example, "num. IsEven. For this reason, you can consider changing some methods in the static tool class in the Code into extension methods. Of course, the extension method is called just like the instance method, so I want to see at a glance whether a method is not so easy to expand. In fact, it is very well identified in VS. For the above example, put the mouse in VS and you will see "(extention) bool int. how the IsEven () Extension Method is discovered and how to call the extension method is described in the previous section, but it is equally important to know how to not call the extension method. Next let's take a look at how the compiler decides the extension method to be used. The compiler processes extension methods: When the compiler sees an expression that seems to call an instance method, the compiler searches for all instance methods. If no compatible instance method is found, the compiler will find an appropriate extension method. The compiler will check all the imported namespaces and all the extension methods in the current namespace, there is an implicit conversion extension method that matches the variable type to the extension type. When the compiler looks for an extension method, it checks the System. runtime. compilerServices. extensionAttribute to determine whether a method is an extension method. If you see how the compiler handles the extension method, you need to know what to pay attention to when using the extension method. Note: The instance method has a higher priority than the extension method. When the extension method is the same as the instance method signature, the compiler will not give any warning, instead, the instance method is called by default. If there are multiple applicable extension methods, they can be applied to different extension types (using implicit conversion ), then, by applying the "better conversion" rule in the overloaded method, the compiler will select the most appropriate one in the call to the extended method, and there will be a rule, the compiler will call the Extension Method in the nearest namespace. The following is an example. Here is an example to better understand some notes when the compiler processes extension methods: namespace ExtentionMethodTest {using AnotherNameSpace; public static class ExtentionMethods {public static void printInfo (this Student stu) {Console. writeLine ("printInfo (Student) From ExtentionMethodTest "); Console. writeLine ("{0} is {1} years old", stu. name, stu. age);} public static void printInfo (this object stu) {Console. writeLine ("printInfo (object) from ExtentionMethodTest"); Console. writeLine ("{0} is {1} years old", (Student) stu ). name, (Student) stu ). age) ;}} public class Student {public string Name {get; set ;}public int Age {get; set ;}// instance method // public void p RintInfo () // {// Console. writeLine ("{0} is {1} years old", this. name, this. age); //} class Program {static void Main (string [] args) {Student wilber = new Student {Name = "Wilber", Age = 28 }; // when the instance method printInfo exists, all extension methods are invisible // The instance method is called // wilber. printInfo (); // After the instance method is commented out, the following code calls the printInfo method of the latest namespace // At the same time, the following statement selects the extension method of the "better conversion" rule // printInfo (Student) from ExtentionMethodTest // Wilber is 28 years o Ld wilber. printInfo (); // when wilber is converted to the object type, printInfo (this object stu) is called // printInfo (object) from ExtentionMethodTest // Wilber is 28 years old object will = wilber; will. printInfo (); Console. read () ;}} namespace AnotherNameSpace {using ExtentionMethodTest; public static class ExtentionClass {public static void printInfo (this Student stu) {Console. writeLine ("printInfo (Student) from AnotherNa MeSpace "); Console. writeLine ("{0} is {1} years old", stu. name, stu. age) ;}} call the extension method on the null reference. When we call the instance method on the null reference, NullReferenceException is thrown. However, we can call the Extension Method on an empty reference. In the following example, we can determine whether an object is a null reference. Namespace ExtentionMethodTest {public static class NullUitl {public static bool IsNull (this object o) {return o = null ;}} class Program {static void Main (string [] args) {object x = null; Console. writeLine (x. isNull (); x = new object (); Console. writeLine (x. isNull (); Console. read () ;}} as shown in the preceding example, even if the reference is null. isNull () "can still be executed normally. According to the working principle of the extension method we introduced earlier, in fact, the above call will be converted into a static method call by the compiler "NullUitl. isNull (x) "(check the IL code verification), which explains why the extension method can be called on the null reference.

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.