zoukankan      html  css  js  c++  java
  • C#扩展方法入门

    扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 仅当你使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。
    下面的示例演示为 SystemString 类定义的一个扩展方法。 请注意,它是在非嵌套的、非泛型静态类内部定义的:
    namespace ExtensionMethods 
    { 
        public static class MyExtensions 
        { 
            public static int WordCount(this String str) 
            { 
                return str.Split(new char[] { ' ', '.', '?' },  
                                 StringSplitOptions.RemoveEmptyEntries).Length; 
            } 
        }    
    } 
     
    可使用此 using 指令将
    WordCount
    扩展方法置于范围中:
    using ExtensionMethods;
    而且,可以使用以下语法从应用程序中调用该扩展方法:
    string s = "Hello Extension Methods";
    int i = s.WordCount();
    在代码中,可以使用实例方法语法调用该扩展方法。 但是,编译器生成的中间语言 (IL) 会将代码转换为对静态方法的调用。 因此,并未真正违反封装原则。 实际上,扩展方法无法访问它们所扩展的类型中的私有变量。
    通常,你更多时候是调用扩展方法而不是实现你自己的扩展方法。 由于扩展方法是使用实例方法语法调用的,因此不需要任何特殊知识即可从客户端代码中使用它们。 若要为特定类型启用扩展方法,只需为在其中定义这些方法的命名空间添加 using 指令。 例如,若要使用标准查询运算符,请将此 using 指令添加到代码中:

    可以使用扩展方法来扩展类或接口,但不能重写扩展方法。 与接口或类方法具有相同名称和签名的扩展方法永远不会被调用。 编译时,扩展方法的优先级总是比类型本身中定义的实例方法低。 换句话说,如果某个类型具有一个名为Process(int i)的方法,而你有一个具有相同签名的扩展方法,则编译器总是绑定到该实例方法。 当编译器遇到方法调用时,它首先在该类型的实例方法中寻找匹配的方法。 如果未找到任何匹配方法,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到的第一个扩展方法。 下面的示例演示编译器如何确定要绑定到哪个扩展方法或实例方法。

      

    namespace DefineIMyInterface 
    { 
        using System; 
     
        public interface IMyInterface 
        { 
            // Any class that implements IMyInterface must define a method 
            // that matches the following signature. 
            void MethodB(); 
        } 
    } 
     
     
    // Define extension methods for IMyInterface. 
    namespace Extensions 
    { 
        using System; 
        using DefineIMyInterface; 
     
        // The following extension methods can be accessed by instances of any  
        // class 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 in ExtensionMethodsDemo1, because each  
            // of the three classes A, B, and C implements a method named MethodB 
            // that has a matching signature. 
            public static void MethodB(this IMyInterface myInterface) 
            { 
                Console.WriteLine 
                    ("Extension.MethodB(this IMyInterface myInterface)"); 
            } 
        } 
    } 
     
     
    // Define three classes that implement IMyInterface, and then use them to test 
    // the extension methods. 
    namespace ExtensionMethodsDemo1 
    { 
        using System; 
        using Extensions; 
        using DefineIMyInterface; 
     
        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) 
            { 
                // Declare an instance of class A, class B, and class C. 
                A a = new A(); 
                B b = new B(); 
                C c = new C(); 
     
                // For a, b, and c, call the following methods: 
                //      -- MethodA with an int argument 
                //      -- MethodA with a string argument 
                //      -- MethodB with no argument. 
     
                // A contains no MethodA, so each call to MethodA resolves to  
                // the extension method that has a matching signature. 
                a.MethodA(1);           // Extension.MethodA(object, int) 
                a.MethodA("hello");     // Extension.MethodA(object, string) 
     
                // A has a method that matches the signature of the following call 
                // to MethodB. 
                a.MethodB();            // A.MethodB() 
     
                // B has methods that match the signatures of the following 
                // method calls. 
                b.MethodA(1);           // B.MethodA(int) 
                b.MethodB();            // B.MethodB() 
     
                // B has no matching method for the following call, but  
                // class Extension does. 
                b.MethodA("hello");     // Extension.MethodA(object, string) 
     
                // C contains an instance method that matches each of the following 
                // method calls. 
                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() 
     */ 
    

      

  • 相关阅读:
    [ASP.NET] 使用 ASP.NET SignalR 添加实时 Web
    [ORM] Entity Framework(2) CodeFirst进阶
    [ORM] Entity Framework(1) CodeFirst快速入门
    [C#] 谈谈异步编程async await
    [Solution] NPOI操作Excel
    消息队列二
    消息队列一
    redis成长之路——(七)
    redis成长之路——(六)
    redis成长之路——(五)
  • 原文地址:https://www.cnblogs.com/alphafly/p/3872248.html
Copyright © 2011-2022 走看看