(转)c# 扩展方法

2021-07-13 21:16

阅读:561

标签:优先级   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 ListT> : IListT>, ICollectionT>, IList, ICollection, IReadOnlyListT>, IReadOnlyCollectionT>, IEnumerableT>, IEnumerable
    {
        // 摘要: 
        //     Initializes a new instance of the System.Collections.Generic.List 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 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 collection);
        ……
}

在List的类型定义中我们并没有看到有定义Union方法的地方,但是当我们在调用的时候就会出现:

"white-space:pre">	/// /// 通过集合使用
        /// /// 

        /// 

        /// public List UseSetSearchCollection(List needSearchList, int areaid)
        {
            if (needSearchList == null || !needSearchList.Any()) return null;
            const int area15 = 15;
            var area15List = new List();
            const int area16 = 16;
            var area16List = new List();
            const int area17 = 17;
            var area17List = new List();
            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 Union(this IEnumerable first, IEnumerable second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return UnionIterator(first, second, null);
        }
    }
}

so,也就是说,List的一个实例里面可以调用Enumerable里面的Union方法,如果我们不知道有扩展方法这回事的时候,以通常的想法,通过继承关系来找Union方法,会发现,List并没有实现Union方法,而且在继承的接口中也没有定义Union方法。这就比较纳闷了,这不是违背了面向对象的三大基本原则么?此话后说,我们先来自己实现一个扩展方法:

    public interface IFreshListT>
    {
        
    }

    public static class testjinni
    {
        public static IFreshList Union(this IFreshList first, IFreshList second)
        {
            return second;
        }
    }

    public class MyListT> : IFreshListT>
    {
    }

    public class use
    {
        public void meth()
        {
            var temiList=new MyListint>();
            var mdaidnnf = new MyListint>();
           temiList.Union(mdaidnnf);
        }
    }

这只是一个简单的例子,你可以做你自己的扩展方法。

所有对象都能使用扩展:

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

msdn是这样规定扩展方法的:“扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个

类型,并且该参数以 this 修饰符为前缀。”通俗的说就是,扩展方法跟静态类的名称无关,只需要在一个静态类里面定义一个静态方法,第一个参数必须this T开头,

这个T就是一个泛型类型了。

小结:

本质上来说: 扩展方法是破坏原来的层次结构,通过网络结构加快业务逻辑处理;

扩展方法不改变被扩展类的代码,不用重新编译、修改、派生被扩展类;

扩展方法不能访问被扩展类的私有成员;

扩展方法会被被扩展类的同名方法覆盖,所以实现扩展方法我们需要承担随时被覆盖的风险;

扩展方法看似实现了面向对象中扩展对修改说不的特性,但是也违背了面向对象的继承原则,被扩展类的派生类是不能继承扩展扩展方法的,从而又违背了面向对象的多态性。;

在我们稳定的引用同一个版本的类库,但是我们没有该类库的源代码,那么我们可以使用扩展方法;但是从项目的可扩展、可维护和版本控制方面来说,都不建议使用扩展方法进行类的扩展。

文章转载自:https://blog.csdn.net/qin_zhangyongheng/article/details/52469476

(转)c# 扩展方法

标签:优先级   his   elements   lex   ring   eset   静态   capacity   who   

原文地址:https://www.cnblogs.com/yeshenmeng/p/9559077.html


评论


亲,登录后才可以留言!