擴展方法(static靜態類中靜態函數的參數使用this修飾)

在迄今爲止的內容中,每個方法都和聲明它的類關聯,擴展方法特性擴展了這個邊界,允許編寫的方法和聲明它的類之外的類關聯

    class MyData
    {
        private double D1;
        private double D2;
        private double D3;
        public MyData(double d1,double d2,double d3) 
        {
            D1 = d1;D2 = d2;D3 = d3;
        }
        public double Sum()
        {
            return D1 + D2 + D3;
        }
    }

如上面的代碼所示,這是一個有限的類,假設它還需要含有另一個方法,這個方法返回3個數據的平均值,則有這幾種方法可以實現:
(1)如果有源代碼,只需要添加一個新方法即可
(2)如果不能修改這個類(如這個類在一個第三方類庫中),那麼只要它不是密封的,你就能把它用作一個基類在派生自它的類中實現這個額外的方法。
(3)如果不能訪問代碼,或者該類是密封的,就不得不在另一個類中使用該類的公有可用成員編寫一個方法,例如可以編寫一個下面這樣的類,該類中方法接受MyData的實例作爲參數來完成相應的需求。

    static class ExtendMyData
    {
        public static double Average(MyData md)
        {
            return md.Sum() / 3;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyData md = new MyData(3, 4, 5);
            Console.WriteLine(ExtendMyData.Average(md));
        }
    }

儘管這是非常好的解決方案,但如果能在類的實例自身上調用該方法會更優雅,也就是第二種調用方法。
ExtendMyData.Average(md); //靜態調用形式
md.Average();  //實例調用形式

而擴展方法允許你使用第二種形式,通過對Average的聲明做一個改動,就可以使用實例調用形式,做法就是在參數聲明中的類型前增加關鍵字this,如下面所示,把this加到靜態類的靜態方法的第一個參數上,把該方法從類ExtendMyData的常規方法改變爲類MyData的擴展方法,現在倆種調用形式都可以使用。

    static class ExtendMyData
    {
        public static double Average(this MyData md)
        {
            return md.Sum() / 3;
        }
        public static double foo(this MyData md,int i)
        {
            return md.Sum()+i;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyData md = new MyData(3, 4, 5); 
            Console.WriteLine(ExtendMyData.Average(md));  //4
            Console.WriteLine(md.Average());  //4
            Console.WriteLine(md.foo(100));   //112
        }
    }

擴展方法的重要要求
(1)聲明擴展方法的類必須聲明爲static
(2)擴展方法本身必須聲明爲static
(3)擴展方法必須包含關鍵字this作爲它的第一個參數類型,並在後面跟着它所擴展的類的名稱

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章