zoukankan      html  css  js  c++  java
  • (转)c# 扩展方法

    扩展方法能够向现有类型“添加”方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型。扩展方法必须是静态方法,可以像实例方法一样进行调用。且调用同名中实际定义的方法优先级要高于扩展方法。

    先来看看在经常使用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就是一个泛型类型了。

    小结:

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

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

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

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

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

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

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

  • 相关阅读:
    jquery判断复选框是否选中
    jquery验证网址格式
    jquery右下角返回顶部
    thinkphp分页格式的完全自定义,直接输入数字go到输入数字页
    textarea出现多余的空格
    html渐隐轮播
    linux 路由 route
    ansible 自动化运维工具
    数据库 group by 后其他列的取值
    linux 磁盘io高排查
  • 原文地址:https://www.cnblogs.com/yeshenmeng/p/9559077.html
Copyright © 2011-2022 走看看