Extension Method In .Net

Extension method enable you to "add" your methods to the existing type without creating a new derived type, recompiling

or otherwise modifying the original type. Extension methods are a special type of static methods, but they are called as if they were instance type on the extended type.

 

The most common extension methods are the LINQ standard query operators that add query functionality to the existing System.Collections.IEnumerable and  System.Collections.Generic.IEnumerable(T) types. To use the standard query operator, first bring them into scope with a using System.Linq directive. 

 

The following example shows how to call the standard query method OrderBy method on an array of integers.


 

    class Program

    {

        static void Main(string[] args)

        {

            int[] ints = { 10, 45, 15, 39, 21, 26 };

            var result = ints.OrderBy(item => item);

            foreach (int i in result)

            {

                System.Console.Write(i + " ");

            }

        }

     }

//Output:10 15 21 26 39 45

 

Extension method are defined as static methods but are used as instance method syntax. Their first parameter specified which type the method operators on, and the parameter is preceded by this modifier. Extension methods are only in scope when you explicitly import the namespace into your code with using.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}
 
using ExtensionMethods;
string s = "Hello Extension Methods";
int i = s.WordCount();

Note:
1. the parameter this String str present for the instance of the extended type. the other parameters is the real 
parameters for the extension method(int i = s.WordCount();).
2. Actually, the extension method cannot access the private member of the they that will be extended.
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named Process(int i), and you have an extension method with the same signature, the compiler will always bind to the instance method. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it will search for any extension methods that are defined for the type, and bind to the first extension method that it finds. The following example demonstrates how the compiler determines which extension method or instance method to bind to.

The following example demonstrates the rules that the C# compiler follows in determining whether to bind a method call to an instance method on the type, or to an extension method. The static class Extensions contains extension methods defined for any type that implementsIMyInterface. Classes AB, and C all implement the interface.

The MethodB method is never called because its name and signature exactly match methods already implemented by the classes.

When the compiler cannot find an instance method with a matching signature, it will bind to a matching extension method if one exists.

C#
namespace Extensions
{
  using System;
  using ExtensionMethodsDemo1;

     // Define extension methods for any type that implements IMyInterface.
     public static class Extension
     {
        public static void MethodA(this IMyInterface myInterface, int i)
        {
            Console.WriteLine("Extension.MethodA(this IMyInterface myInterface, int i)");
        }

        public static void MethodA(this IMyInterface myInterface, string s) 
        {
            Console.WriteLine("Extension.MethodA(this IMyInterface myInterface, string s)");
        }

        // This method is never called, because the three classes implement MethodB.
        public static void MethodB(this IMyInterface myInterface) 
        {
            Console.WriteLine("Extension.MethodB(this IMyInterface myInterface)");
        }
    }
}
namespace ExtensionMethodsDemo1
{
    using System;
    using Extensions;

    public interface IMyInterface
    {
        void MethodB();
    }

    class A : IMyInterface 
    {
        public void MethodB(){Console.WriteLine("A.MethodB()");}
    } 

    class B : IMyInterface
    {
        public void MethodB() { Console.WriteLine("B.MethodB()"); }
        public void MethodA(int i) { Console.WriteLine("B.MethodA(int i)"); }
    }

    class C : IMyInterface
    {
        public void MethodB() { Console.WriteLine("C.MethodB()"); }
        public void MethodA(object obj) { Console.WriteLine("C.MethodA(object obj)"); }
    }

    class ExtMethodDemo
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            C c = new C();
            TestMethodBinding(a,b,c);
        }

        static void TestMethodBinding(A a, B b, C c)
        {
            // A has no methods, so each call resolves to 
            // the extension methods whose signatures match.
            a.MethodA(1);           // Extension.MethodA(object, int)
            a.MethodA("hello");     // Extension.MethodA(object, string)
            a.MethodB();            // A.MethodB()

            // B itself has a method with this signature.
            b.MethodA(1);           // B.MethodA(int)
            b.MethodB();            // B.MethodB()

            // B has no matching method, but Extension does.
            b.MethodA("hello");     // Extension.MethodA(object, string)

            // In each case C has a matching instance method.
            c.MethodA(1);           // C.MethodA(object)
            c.MethodA("hello");     // C.MethodA(object)
            c.MethodB();            // C.MethodB()
        }
    }
}
/* Output:
    Extension.MethodA(this IMyInterface myInterface, int i)
    Extension.MethodA(this IMyInterface myInterface, string s)
    A.MethodB()
    B.MethodA(int i)
    B.MethodB()
    Extension.MethodA(this IMyInterface myInterface, string s)
    C.MethodA(object obj)
    C.MethodA(object obj)
    C.MethodB()
 */

If you do implement extension methods for a given type, remember the following two points:

  • An extension method will never be called if it has the same signature as a method defined in the type.

  • Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值