c# 擴充方法

來源:互聯網
上載者:User

標籤:優先順序   his   elements   lex   ring   eset   靜態   capacity   who   

擴充方法能夠向現有類型“添加”方法,而無需建立新的衍生類別型,重新編譯或以其他方式修改原始類型。擴充方法必須是靜態方法,可以像執行個體方法一樣進行調用。且調用同名中實際定義的方法優先順序要高於擴充方法。

先來看看在經常使用List類型中使用擴充方法的例子,首先看看List是如何定義的:

    // 摘要:     //     Represents a strongly typed list of objects that can be accessed by index.    //     Provides methods to search, sort, and manipulate lists.To browse the .NET    //     Framework source code for this type, see the Reference Source.    //    // 型別參數:     //   T:    //     The type of elements in the list.    [Serializable]    [DebuggerDisplay("Count = {Count}")]    [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]    public class List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable    {        // 摘要:         //     Initializes a new instance of the System.Collections.Generic.List<T> class        //     that is empty and has the default initial capacity.        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]        public List();        //        // 摘要:         //     Initializes a new instance of the System.Collections.Generic.List<T> class        //     that contains elements copied from the specified collection and has sufficient        //     capacity to accommodate the number of elements copied.        //        // 參數:         //   collection:        //     The collection whose elements are copied to the new list.        //        // 異常:         //   System.ArgumentNullException:        //     collection is null.        public List(IEnumerable<T> collection);        ……}

在List的類型定義中我們並沒有看到有定義Union方法的地方,但是當我們在調用的時候就會出現:

<span style="white-space:pre"></span>/// <summary>        /// 通過集合使用        /// </summary>        /// <param name="needSearchList"></param>        /// <param name="areaid"></param>        /// <returns></returns>        public List<AreaLineInfoModel> UseSetSearchCollection(List<AreaLineInfoModel> needSearchList, int areaid)        {            if (needSearchList == null || !needSearchList.Any()) return null;            const int area15 = 15;            var area15List = new List<AreaLineInfoModel>();            const int area16 = 16;            var area16List = new List<AreaLineInfoModel>();            const int area17 = 17;            var area17List = new List<AreaLineInfoModel>();            needSearchList.ForEach(                m =>                {                    if (m.AreaIdList.Contains(area15)) area15List.Add(m);                    if (m.AreaIdList.Contains(area16)) area16List.Add(m);                    if (m.AreaIdList.Contains(area17)) area17List.Add(m);                });            if (areaid == area15) return area15List.Union(area16List).Union(area17List).ToList();            if (areaid == area16) return area16List.Union(area15List).Union(area17List).ToList();            if (areaid == area17) return area17List.Union(area15List).Union(area16List).ToList();            return null;        }

其中的Union方法哪裡來的呢?我們轉到定義看一看:

namespace System.Linq{    public static class Enumerable    {         ……         public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {            if (first == null) throw Error.ArgumentNull("first");            if (second == null) throw Error.ArgumentNull("second");            return UnionIterator<TSource>(first, second, null);        }    }}

so,也就是說,List的一個執行個體裡面可以調用Enumerable裡面的Union方法,如果我們不知道有擴充方法這回事的時候,以通常的想法,通過繼承關係來找Union方法,會發現,List並沒有實現Union方法,而且在繼承的介面中也沒有定義Union方法。這就比較納悶了,這不是違背了物件導向的三大基本原則嗎?此話後說,我們先來自己實現一個擴充方法:

    public interface IFreshList<T>    {            }    public static class testjinni    {        public static IFreshList<TSource> Union<TSource>(this IFreshList<TSource> first, IFreshList<TSource> second)        {            return second;        }    }    public class MyList<T> : IFreshList<T>    {    }    public class use    {        public void meth()        {            var temiList=new MyList<int>();            var mdaidnnf = new MyList<int>();           temiList.Union(mdaidnnf);        }    }

這隻是一個簡單的例子,你可以做你自己的擴充方法。

所有對象都能使用擴充:

public static class ExtendExt
{
  public static void FuncExt(this object obj)
  {
    int b = 0;
  }
}

msdn是這樣規定擴充方法的:“擴充方法被定義為靜態方法,但它們是通過執行個體方法文法進行調用的。 它們的第一個參數指定該方法作用於哪個

類型,並且該參數以 this 修飾符為首碼。”通俗的說就是,擴充方法跟靜態類的名稱無關,只需要在一個靜態類裡面定義一個靜態方法,第一個參數必須this T開頭,

這個T就是一個泛型型別了。

小結:

本質上來說: 擴充方法是破壞原來的階層,通過網路結構加快商務邏輯處理;

擴充方法不改變被擴充類的代碼,不用重新編譯、修改、派生被擴充類;

擴充方法不能訪問被擴充類的私人成員;

擴充方法會被被擴充類的同名方法覆蓋,所以實現擴充方法我們需要承擔隨時被覆蓋的風險;

擴充方法看似實現了物件導向中擴充對修改說不的特性,但是也違背了物件導向的繼承原則,被擴充類的衍生類別是不能繼承擴充擴充方法的,從而又違背了物件導向的多態性。;

在我們穩定的引用同一個版本的類庫,但是我們沒有該類庫的原始碼,那麼我們可以使用擴充方法;但是從項目的可擴充、可維護和版本控制方面來說,都不建議使用擴充方法進行類的擴充。

文章轉載自:52469476

(轉)c# 擴充方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.