扩展方法学习发展之路

大学学习的java,工作后转成了C#,由于工作需要,全力去学习了C#,学习中,相信大家都会有相同的疑惑,在判断一个字符串是否为空的时候总会用到string.IsNullOrEmpty(s)这个方法,最开始就想到了是不是反射,后面才知道这是c#的扩展方法,后面的内容慢慢讲解我对扩展方法由浅到深的理解与用法。

1:扩展方法的自定义实现,我这里特别用到了判断类型是否为数值类型的方法(可以去比较学习下),里面子定义了4个扩展方法

 1 namespace ConsoleApplication1
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             var i = 32;
 8             System.Console.WriteLine(i.GetType().IsNumericType());
 9             System.Console.ReadKey();
10         }
11     }
12
13     public static class TestExtension
14     {
15         //老外的代码
16         public static bool IsNumeric(this Type dataType)
17         {
18             if (dataType == null)
19                 throw new ArgumentNullException("dataType");
20
21             return (dataType == typeof(int)
22                     || dataType == typeof(double)
23                     || dataType == typeof(long)
24                     || dataType == typeof(short)
25                     || dataType == typeof(float)
26                     || dataType == typeof(Int16)
27                     || dataType == typeof(Int32)
28                     || dataType == typeof(Int64)
29                     || dataType == typeof(uint)
30                     || dataType == typeof(UInt16)
31                     || dataType == typeof(UInt32)
32                     || dataType == typeof(UInt64)
33                     || dataType == typeof(sbyte)
34                     || dataType == typeof(Single)
35                    );
36         }
37         /// <summary>
38         /// 判断是否为数值类型。
39         /// </summary>
40         /// <param name="t">要判断的类型</param>
41         /// <returns>是否为数值类型</returns>
42         public static bool IsNumericType(this Type t)
43         {
44             var tc = Type.GetTypeCode(t);
45             return (t.IsPrimitive && t.IsValueType && !t.IsEnum && tc != TypeCode.Char && tc != Typ               eCode.Boolean) || tc == TypeCode.Decimal;
46         }
47
48         /// <summary>
49         /// 判断是否为可空数值类型。
50         /// </summary>
51         /// <param name="t">要判断的类型</param>
52         /// <returns>是否为可空数值类型</returns>
53         public static bool IsNumericOrNullableNumericType(this Type t)
54         {
55             return t.IsNumericType() || (t.IsNullableType() && t.GetGenericArguments()[0].IsNumeric               Type());
56         }
57
58         /// <summary>
59         /// 判断是否为可空类型。
60         /// 注意,直接调用可空对象的.GetType()方法返回的会是其泛型值的实际类型,用其进行此判断肯定返回false。
61         /// </summary>
62         /// <param name="t">要判断的类型</param>
63         /// <returns>是否为可空类型</returns>
64         public static bool IsNullableType(this Type t)
65         {
66             return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
67         }
68
69     }
70 }

2:通过上面的列子可能就只能看出它使用上更为便捷而已,但当我接触到Linq,才发现扩展方法的强大,自己也学着参考改造下Linq的构造方法以增加增加所需要的功能

 1 public static class QueryableExtensions
 2     {
 3         public static IQueryable<T> OrderBy<T>(this IQueryable<T> queryable, string propertyName)
 4         {
 5             return QueryableHelper<T>.OrderBy(queryable, propertyName, false);
 6         }
 7         public static IQueryable<T> OrderBy<T>(this IQueryable<T> queryable, string propertyName, b           ool desc)
 8         {
 9             return QueryableHelper<T>.OrderBy(queryable, propertyName, desc);
10         }
11
12         static class QueryableHelper<T>
13         {
14             //为了缓存表达式树
15             private static Dictionary<string, LambdaExpression> cache = new Dictionary<string, Lamb               daExpression>();
16             public static IQueryable<T> OrderBy(IQueryable<T> queryable, string propertyName, bool                desc)
17             {
18
19                 dynamic keySelector = GetLambdaExpression(propertyName);
20                 return desc ? Queryable.OrderByDescending(queryable, keySelector) : Queryable.Order                   By(queryable, keySelector);
21             }
22             private static LambdaExpression GetLambdaExpression(string propertyName)
23             {
24                 if (cache.ContainsKey(propertyName)) return cache[propertyName];
25                 var param = Expression.Parameter(typeof(T));
26                 var body = Expression.Property(param, propertyName);
27                 var keySelector = Expression.Lambda(body, param);
28                 cache[propertyName] = keySelector;
29                 return keySelector;
30             }
31         }
32     }

4:对于数据库的操作,也可以使用扩展方法,我上篇随笔也说了,项目用了IOC,没有在数据库这块用到扩展方法,这可以参考http://www.cnblogs.com/xiaotuni/archive/2012/05/29/2523683.html

5:当使用到MVC框架的时候,看到前端的页面使用Html.BeginForm等一些相同格式语法的时候,我马上意识到这就是MVC里面的扩展方法,转而想是否可以自己也写一些扩展方法,方便自己使用,首先我想到前端Table的遍历,分页等,并着手全部实现,并应用于项目中

Table的遍历,我们在后台写好一个扩展方法类

 1  public static class RazorExtensions
 2     {
 3         public static HelperResult /*List*/ Repeat<T>(this IEnumerable<T> items,
 4             Func<T, HelperResult> template)
 5         {
 6             if (items == null)
 7                 return new HelperResult(t => t.Write(""));
 8
 9             return new HelperResult(writer =>
10             {
11                 foreach (var item in items)
12                 {
13                     template(item).WriteTo(writer);
14                 }
15             });
16         }
17 }

前端我们引用他的命名空间,如下方式调用:

<tbody>
                @Model.Repeat(
                    @<tr>
                         <td><ahref="/order/catalog/new/@item.ContractNo">@item.ContractNo</a></td>
                         <td>@item.StrokeNo</td>
                         <td>@item.StrokeDesc</td>
                         <td>@item.ContractStatus</td>
                         <td>@item.DeptNo</td>
                         <td>@item.Season</td>
                         <td>@item.SupplierSeries</td>
                         <td>@item.CountryCode</td>
                         <td>@item.ProductDesc</td>
                         <td>@item.DateLastModified</td>
                         <td>@item.CreatedTime.Format()</td>
                     </tr>)
            </tbody>

分页控件的实现:

后台:首先我们必须有一个page类

namespace WebPrint.Web.Mvc.Pager
{
    public class PagerOptions
    {
        public PagerOptions()
        {
            AutoHide = true;
            PageIndexParameterName = "pageindex";
            NumericPagerItemCount = 10;
            AlwaysShowFirstLastPageNumber = false;
            ShowPrevNext = true;
            NextPageText = "&gt;";
            PrevPageText = "&lt;";
            ShowNumericPagerItems = true;
            ShowFirstLast = true;
            FirstPageText = "&lt;&lt;";
            LastPageText = "&gt;&gt";
            ShowMorePagerItems = true;
            MorePageText = "...";
            ShowDisabledPagerItems = true;
            PagerItemsSeperator = "  ";
            ContainerTagName = "div";
            InvalidPageIndexErrorMessage = "页索引无效";
            PageIndexOutOfRangeErrorMessage = "页索引超出范围";
            MaxPageIndex = 0;
            FirstPageRouteName = null;
        }
        /// <summary>
        /// 首页使用的路由名称(无页索引参数)
        /// </summary>
        public string FirstPageRouteName { get; set; }
        /// <summary>
        /// 当总页数只有一页时是否自动隐藏
        /// </summary>
        public bool AutoHide { get; set; }
        /// <summary>
        /// 页索引超出范围时显示的错误消息
        /// </summary>
        public string PageIndexOutOfRangeErrorMessage { get; set; }
        /// <summary>
        /// 页索引无效时显示的错误消息
        /// </summary>
        public string InvalidPageIndexErrorMessage { get; set; }
        /// <summary>
        /// url中页索引参数的名称
        /// </summary>
        public string PageIndexParameterName { get; set; }

        private string _containerTagName;
        /// <summary>
        /// 分页控件html容器标签名,默认为div
        /// </summary>
        public string ContainerTagName
        {
            get
            {
                return _containerTagName;
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new System.ArgumentException("ContainerTagName不能为null或空字符串", "ContainerTagName");
                _containerTagName = value;
            }
        }
        /// <summary>
        /// whether or not show first and last numeric page number
        /// </summary>
        public bool AlwaysShowFirstLastPageNumber { get; set; }
        /// <summary>
        /// 显示的最大数字页索引按钮数
        /// </summary>
        public int NumericPagerItemCount { get; set; }
        /// <summary>
        /// 是否显示上页和下页
        /// </summary>
        public bool ShowPrevNext { get; set; }
        /// <summary>
        /// 上一页文本
        /// </summary>
        public string PrevPageText { get; set; }
        /// <summary>
        /// 下一页文本
        /// </summary>
        public string NextPageText { get; set; }
        /// <summary>
        /// 是否显示数字页索引按钮及更多页按钮
        /// </summary>
        public bool ShowNumericPagerItems { get; set; }
        /// <summary>
        /// 是否显示第一页和最后一页
        /// </summary>
        public bool ShowFirstLast { get; set; }
        /// <summary>
        /// 第一页文本
        /// </summary>
        public string FirstPageText { get; set; }
        /// <summary>
        /// 最后一页文本
        /// </summary>
        public string LastPageText { get; set; }
        /// <summary>
        /// 是否显示更多页按钮
        /// </summary>
        public bool ShowMorePagerItems { get; set; }
        /// <summary>
        /// 更多页按钮文本
        /// </summary>
        public string MorePageText { get; set; }
        /// <summary>
        /// 包含分页控件的父容器标签的ID
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// CSS样式类
        /// </summary>
        public string CssClass { get; set; }
        /// <summary>
        /// whether or not show disabled navigation buttons
        /// </summary>
        public bool ShowDisabledPagerItems { get; set; }
        /// <summary>
        /// 分页元素之间的分隔符,默认为两个html空格(  )
        /// </summary>
        public string PagerItemsSeperator { get; set; }
        /// <summary>
        /// 限制显示的最大页数,默认值为0,即根据总记录数算出的总页数
        /// </summary>
        public int MaxPageIndex { get; set; }
    }
}

2个生成分页控件HTML代码的类

using System;
using System.Web.Mvc;
using System.Web.Routing;
using WebPrint.Model.Helper;

namespace WebPrint.Web.Mvc.Pager
{
    public static class PagerHelper
    {
        #region Html Pager

        private static MvcHtmlString Pager(this HtmlHelper helper, int totalItemCount, int pageSize, int pageIndex,
            string actionName, string controllerName,
            PagerOptions pagerOptions, string routeName, object routeValues, object htmlAttributes)
        {
            var totalPageCount = (int) Math.Ceiling(totalItemCount/(double) pageSize);
            var builder = new PagerBuilder
                (
                helper,
                actionName,
                controllerName,
                totalItemCount,
                totalPageCount,
                pageIndex,
                pageSize,
                pagerOptions,
                routeName,
                new RouteValueDictionary(routeValues),
                new RouteValueDictionary(htmlAttributes)
                );
            return builder.RenderPager();
        }

        public static MvcHtmlString Pager(this HtmlHelper helper, IPagedList pagedList, PagerOptions pagerOptions)
        {
            //if (pagedList == null)
            //    return Pager(helper, pagerOptions, null);
            return Pager(helper, pagedList.RecordsCount, pagedList.PageSize, pagedList.PageIndex, null, null,
                pagerOptions, null, null, null);
        }

        #endregion
    }
}

/*
 ASP.NET MvcPager 分页组件
 [email protected]杨涛\Webdiyer (http://www.webdiyer.com)
 Source code released under Ms-PL license
 */

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace WebPrint.Web.Mvc.Pager
{
    internal class PagerBuilder
    {
        private readonly HtmlHelper html;
        private readonly string actionName;
        private readonly string controllerName;
        private readonly int totalPageCount = 1;
        private readonly int totalRecordCount = 1;
        private readonly int pageIndex;
        private readonly int pageSize;
        private readonly PagerOptions pagerOptions;
        private readonly RouteValueDictionary routeValues;
        private readonly string routeName;
        private readonly int startPageIndex = 1;
        private readonly int endPageIndex = 1;
        private IDictionary<string, object> htmlAttributes;

        private const string CopyrightText =
            "\r\n<!--MvcPager v2.0 for ASP.NET MVC 4.0+ © 2009-2013 Webdiyer (http://www.webdiyer.com)-->\r\n";

        /// <summary>
        /// 适用于PagedList为null时
        /// </summary>
        //internal PagerBuilder(HtmlHelper html,PagerOptions pagerOptions, IDictionary<string, object> htmlAttributes)
        //{
        //    if (pagerOptions == null)
        //        pagerOptions = new PagerOptions();
        //    this.html = html;
        //    this.pagerOptions = pagerOptions;
        //    this.htmlAttributes = htmlAttributes;
        //}
        internal PagerBuilder(HtmlHelper html, string actionName, string controllerName, int totalRecordCount,
            int totalPageCount, int pageIndex, int pageSize, PagerOptions pagerOptions, string routeName,
            RouteValueDictionary routeValues,
            IDictionary<string, object> htmlAttributes)
        {
            if (pagerOptions == null)
                pagerOptions = new PagerOptions();
            this.html = html;
            this.actionName = actionName;
            this.controllerName = controllerName;
            this.totalRecordCount = totalRecordCount;
            if (pagerOptions.MaxPageIndex == 0 || pagerOptions.MaxPageIndex > totalPageCount)
                this.totalPageCount = totalPageCount;
            else
                this.totalPageCount = pagerOptions.MaxPageIndex;
            this.pageIndex = pageIndex;
            this.pageSize = pageSize;
            this.pagerOptions = pagerOptions;
            this.routeName = routeName;
            this.routeValues = routeValues;
            this.htmlAttributes = htmlAttributes;
            // start page index
            startPageIndex = pageIndex - (pagerOptions.NumericPagerItemCount/2);
            if (startPageIndex + pagerOptions.NumericPagerItemCount > this.totalPageCount)
                startPageIndex = this.totalPageCount + 1 - pagerOptions.NumericPagerItemCount;
            if (startPageIndex < 1)
                startPageIndex = 1;
            // end page index
            endPageIndex = startPageIndex + this.pagerOptions.NumericPagerItemCount - 1;
            if (endPageIndex > this.totalPageCount)
                endPageIndex = this.totalPageCount;
        }

        private void AddPrevious(ICollection<PagerItem> results)
        {
            var item = new PagerItem(pagerOptions.PrevPageText, pageIndex - 1, pageIndex == 1, PagerItemType.PrevPage);
            if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                results.Add(item);
        }

        private void AddFirst(ICollection<PagerItem> results)
        {
            var item = new PagerItem(pagerOptions.FirstPageText, 1, pageIndex == 1, PagerItemType.FirstPage);
            //只有导航按钮未被禁用,或导航按钮被禁用但ShowDisabledPagerItems=true时才添加
            if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                results.Add(item);
        }

        private void AddMoreBefore(ICollection<PagerItem> results)
        {
            if (startPageIndex > 1 && pagerOptions.ShowMorePagerItems)
            {
                var index = startPageIndex - 1;
                if (index < 1) index = 1;
                var item = new PagerItem(pagerOptions.MorePageText, index, false, PagerItemType.MorePage);
                results.Add(item);
            }
        }

        private void AddPageNumbers(ICollection<PagerItem> results)
        {
            for (var pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
            {
                var text = pageIndex.ToString(CultureInfo.InvariantCulture);
                //if (pageIndex == this.pageIndex && !string.IsNullOrEmpty(pagerOptions.CurrentPageNumberFormatString))
                //    text = String.Format(pagerOptions.CurrentPageNumberFormatString, text);
                //else if (!string.IsNullOrEmpty(pagerOptions.PageNumberFormatString))
                //    text = String.Format(pagerOptions.PageNumberFormatString, text);
                var item = new PagerItem(text, pageIndex, false, PagerItemType.NumericPage);
                results.Add(item);
            }
        }

        private void AddMoreAfter(ICollection<PagerItem> results)
        {
            if (endPageIndex < totalPageCount)
            {
                var index = startPageIndex + pagerOptions.NumericPagerItemCount;
                if (index > totalPageCount)
                {
                    index = totalPageCount;
                }
                var item = new PagerItem(pagerOptions.MorePageText, index, false, PagerItemType.MorePage);
                results.Add(item);
            }
        }

        private void AddNext(ICollection<PagerItem> results)
        {
            var item = new PagerItem(pagerOptions.NextPageText, pageIndex + 1, pageIndex >= totalPageCount,
                PagerItemType.NextPage);
            if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                results.Add(item);
        }

        private void AddLast(ICollection<PagerItem> results)
        {
            var item = new PagerItem(pagerOptions.LastPageText, totalPageCount, pageIndex >= totalPageCount,
                PagerItemType.LastPage);
            if (!item.Disabled || (item.Disabled && pagerOptions.ShowDisabledPagerItems))
                results.Add(item);
        }

        /// <summary>
        /// 根据页索引生成分页导航Url
        /// </summary>
        /// <param name="pageIndex">要生成导航链接的页索引</param>
        /// <returns>分页导航链接Url</returns>
        private string GenerateUrl(int pageIndex)
        {
            ViewContext viewContext = html.ViewContext;
            //若要生成url的页索引小于1或大于总页数或等于当前页索引时,无需生成分页导航链接
            if (pageIndex > totalPageCount || pageIndex == this.pageIndex)
                return null;
            var routeValues1 = new RouteValueDictionary(viewContext.RouteData.Values);
            AddQueryStringToRouteValues(routeValues1, viewContext);
            if (this.routeValues != null && this.routeValues.Count > 0)
            {
                foreach (var de in this.routeValues)
                {
                    if (!routeValues1.ContainsKey(de.Key))
                    {
                        routeValues1.Add(de.Key, de.Value);
                    }
                    else
                    {
                        routeValues1[de.Key] = de.Value; //手动添加的RouteValues具有高优先级
                    }
                }
            }
            var pageValue = viewContext.RouteData.Values[pagerOptions.PageIndexParameterName];
            string routeName = this.routeName;
            // 设置Route Value中的分页导航Url参数值,pageIndex为0时生成适用于脚本的导航链接
            if (pageIndex == 0)
                routeValues1[pagerOptions.PageIndexParameterName] = "__" + pagerOptions.PageIndexParameterName + "__";
            else
            {
                if (pageIndex == 1)
                {
                    if (!string.IsNullOrWhiteSpace(pagerOptions.FirstPageRouteName))
                        //如果显式指定了FirstPageRouteName,则使用此Route
                    {
                        routeName = pagerOptions.FirstPageRouteName;
                        routeValues1.Remove(pagerOptions.PageIndexParameterName); //去除页索引参数
                        viewContext.RouteData.Values.Remove(pagerOptions.PageIndexParameterName);
                    }
                    else
                    {
                        var curRoute = viewContext.RouteData.Route as Route;
                        //判断当前Route是否为Route类型,如果是,则判断该Route中页索引参数默认值是否为UrlParameter.Optional,或页索引参数是否存在于该Route Url的参数列表中,如果参数默认值为UrlParameter.Optional或分页参数名不存在于Route Url参数中,则从当前的RouteValue列表中去除该参数
                        if (curRoute != null &&
                            (curRoute.Defaults[pagerOptions.PageIndexParameterName] == UrlParameter.Optional ||
                             !curRoute.Url.Contains("{" + pagerOptions.PageIndexParameterName + "}")))
                        {
                            routeValues1.Remove(pagerOptions.PageIndexParameterName); //去除页索引参数
                            viewContext.RouteData.Values.Remove(pagerOptions.PageIndexParameterName);
                        }
                        else
                        {
                            routeValues1[pagerOptions.PageIndexParameterName] = pageIndex;
                        }
                    }
                }
                else
                {
                    routeValues1[pagerOptions.PageIndexParameterName] = pageIndex;
                }
            }
            var routes = html.RouteCollection;
            string url;
            if (!string.IsNullOrEmpty(routeName))
                url = UrlHelper.GenerateUrl(routeName, actionName, controllerName, routeValues1, routes,
                    viewContext.RequestContext, false);
            else
                url = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues1, routes,
                    viewContext.RequestContext, false);
            if (pageValue != null)
                viewContext.RouteData.Values[pagerOptions.PageIndexParameterName] = pageValue;
            return url;
        }

        /// <summary>
        /// 生成最终的分页Html代码
        /// </summary>
        /// <returns></returns>
        internal MvcHtmlString RenderPager()
        {
            //return null if total page count less than or equal to 1
            if (totalPageCount <= 1 && pagerOptions.AutoHide)
                return MvcHtmlString.Create(CopyrightText);
            //Display error message if pageIndex out of range
            if ((pageIndex > totalPageCount && totalPageCount > 0) || pageIndex < 1)
            {
                return
                    MvcHtmlString.Create(string.Format("{0}<div style=\"color:red;font-weight:bold\">{1}</div>{0}",
                        CopyrightText, pagerOptions.PageIndexOutOfRangeErrorMessage));
            }

            var pagerItems = new List<PagerItem>();
            //First page
            if (pagerOptions.ShowFirstLast)
                AddFirst(pagerItems);
            // Prev page
            if (pagerOptions.ShowPrevNext)
                AddPrevious(pagerItems);
            if (pagerOptions.ShowNumericPagerItems)
            {
                if (pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 1)
                    pagerItems.Add(new PagerItem("1", 1, false, PagerItemType.NumericPage));
                // more page before numeric page buttons
                if (pagerOptions.ShowMorePagerItems &&
                    ((!pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 1) ||
                     (pagerOptions.AlwaysShowFirstLastPageNumber && startPageIndex > 2)))
                    AddMoreBefore(pagerItems);
                // numeric page
                AddPageNumbers(pagerItems);
                // more page after numeric page buttons
                if (pagerOptions.ShowMorePagerItems &&
                    ((!pagerOptions.AlwaysShowFirstLastPageNumber && endPageIndex < totalPageCount) ||
                     (pagerOptions.AlwaysShowFirstLastPageNumber && totalPageCount > endPageIndex + 1)))
                    AddMoreAfter(pagerItems);
                if (pagerOptions.AlwaysShowFirstLastPageNumber && endPageIndex < totalPageCount)
                    pagerItems.Add(new PagerItem(totalPageCount.ToString(CultureInfo.InvariantCulture), totalPageCount,
                        false,
                        PagerItemType.NumericPage));
            }
            // Next page
            if (pagerOptions.ShowPrevNext)
                AddNext(pagerItems);
            //Last page
            if (pagerOptions.ShowFirstLast)
                AddLast(pagerItems);
            var sb = new StringBuilder();

            foreach (PagerItem item in pagerItems)
            {
                sb.Append(GeneratePagerElement(item));
            }

            var tb = new TagBuilder(pagerOptions.ContainerTagName);
            if (!string.IsNullOrEmpty(pagerOptions.Id))
                tb.GenerateId(pagerOptions.Id);
            if (!string.IsNullOrEmpty(pagerOptions.CssClass))
                tb.AddCssClass(pagerOptions.CssClass);
            tb.MergeAttributes(htmlAttributes, true);
            sb.Length -= pagerOptions.PagerItemsSeperator.Length;

            var startRecords = ((pageIndex - 1)*pageSize) + 1;
            var endRecords = pageIndex*pageSize;
            if (endRecords > totalRecordCount)
                endRecords = totalRecordCount;

            var recordsCountText =
                string.Format("<span class=\"summary\">{0}&nbsp;-&nbsp;{1},&nbsp;{2}&nbsp;records</span>",
                    startRecords, endRecords, totalRecordCount);
            tb.InnerHtml = sb.ToString() + recordsCountText;

            return
                MvcHtmlString.Create(CopyrightText + /*pagerScript +*/ tb.ToString(TagRenderMode.Normal) + CopyrightText);
        }

        private MvcHtmlString GeneratePagerElement(PagerItem item)
        {
            //pager item link
            string url = GenerateUrl(item.PageIndex);
            if (item.Disabled) //first,last,next or previous page
                return CreateWrappedPagerElement(item,
                    String.Format("<a class=\"disabled\" disabled=\"disabled\">{0}</a>", item.Text));
            return CreateWrappedPagerElement(item,
                string.IsNullOrEmpty(url)
                    ? HttpUtility.HtmlEncode(item.Text)
                    : String.Format("<a href=\"{0}\">{1}</a>", url, item.Text));
        }

        private MvcHtmlString CreateWrappedPagerElement(PagerItem item, string el)
        {
            string navStr = el;
            switch (item.Type)
            {
                case PagerItemType.FirstPage:
                case PagerItemType.LastPage:
                case PagerItemType.NextPage:
                case PagerItemType.PrevPage:
                    break;
                case PagerItemType.MorePage:
                    break;
                case PagerItemType.NumericPage:
                    if (item.PageIndex == pageIndex)
                    {
                        navStr = string.Format("<a href=\"javascript:void(0);\" class=\"current\">{0}</a>", el);
                    }
                    break;
            }
            return MvcHtmlString.Create(navStr + pagerOptions.PagerItemsSeperator);
        }

        private void AddQueryStringToRouteValues(RouteValueDictionary routeValues, ViewContext viewContext)
        {
            if (routeValues == null)
                routeValues = new RouteValueDictionary();
            var rq = viewContext.HttpContext.Request.QueryString;
            if (rq != null && rq.Count > 0)
            {
                var invalidParams = new[]
                {"x-requested-with", "xmlhttprequest", pagerOptions.PageIndexParameterName.ToLower()};
                foreach (string key in rq.Keys)
                {
                    // 添加url参数到路由中
                    if (!string.IsNullOrEmpty(key) && Array.IndexOf(invalidParams, key.ToLower()) < 0)
                    {
                        var kv = rq[key];
                        routeValues[key] = kv;
                    }
                }
            }
        }
    }
}

使用扩展方法:

public static MvcHtmlString Paginaton(this HtmlHelper helper, IPagedList pagedList)
        {
            var pagerOptions = new PagerOptions
            {
                PageIndexParameterName = "page",
                CssClass = "pagination",
                ShowFirstLast = false,
                AlwaysShowFirstLastPageNumber = true,
                ShowMorePagerItems = true,
                NumericPagerItemCount = 5,
                PagerItemsSeperator = string.Empty,
            };

            return helper.Pager(pagedList, pagerOptions);
        }

前端直接引用调用:

<div class="pagination_div">
   @Html.Paginaton(Model)
</div>

总结:相对于鹤冲天大哥的见解,我对于扩张方法的使用差的太远,但一般的场景也可以用到扩展方法的地方都还是可以轻松应对,所以我们平常就该对深入的学习认识他,才能在后面应用自如

时间: 2024-10-13 17:40:29

扩展方法学习发展之路的相关文章

C#中的扩展方法学习总结

??版权声明:本文由秦元培创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处,本文作者为秦元培,本文标题为C#中的扩展方法学习总结,本文链接为http://qinyuanpei.com/2015/12/05/extend-methods-of-csharp/. ??各位朋友大家好,我是秦元培,欢迎大家关注我的博客.最近偶然接触到了C#中的扩展方法,觉得这个语法特性是一个不错的特性,因此决定在这里系统地对C#中的扩展方法相关内容进行下

C#3.0扩展方法学习篇

什么是类的扩展方法 扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. MSDN Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a

扩展方法学习总结

什么是扩展方法?怎么写扩展方法?下面将一一解答. 首先,用扩展方法的目标是对现有的类提供额外的方法以增强该类的功能. 比方说我们想把字符串的转换成第一个字母大写,其他的字母小写.现在VS并没有提供这样直接转换的功能,如果要用的话就需要截取和拼接字符串才能做到.但是如果用到的多了的话,这样做是很麻烦的.此时,我们就可以给字符串添加一个扩展方法,就像ToUpper,ToLower一样,直接点出来转换就可以完成转换. 其次,扩展方法的注意事项 1.扩展方法是一种特殊的静态方法 2.扩展方法必须在静态类

C#扩展方法学习

扩展方法的本质是什么,详细见此文 C#扩展方法,爱你在心口难开 重点如下:扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异. 虽然扩展方法通过实例方法语法进行调用的,但是他们却被定义为静态方法.从定义中我们可以看到,它们的第一个参数指定该方法作用于哪个类型,

JavaScript学习总结(十四)——JavaScript编写类的扩展方法

在?J?a?v?a?S?c?r?i?p?t?中?可以使?用?类的p?r?o?t?o?t?y?p?e属性来?扩?展?类的属?性?和?方?法,在实际开发当中,当JavaScript内置的那些类所提供的动态方法和动态属性不满足我们实际开发时,我们就可以通过"prototype"属性给自定义类添加方法和属性或者扩展原有的类中的方法和属性. 一.扩展JavaScript内置类,添加动态方法 语法格式: 类名.prototype.方法名 = function([param1],[param2],.

扩展方法以及LinQ的学习

我们今天学习的内容其实还是蛮多的,学习了自动属性,扩展方法,复习初始化器,以及LinQ的一些方法,其实感觉有些还是很熟悉的,在前面的学习过程中有时间感觉学习的知识知道了怎么使用,但是还没有在项目中使用,做的习题似乎意义不大,现在依旧如此,感觉仅限于知道怎样使用.很想做一个小小的项目来熟悉下学习的知识...下面就总结下今天学习的内容. 一.自动属性 private int productid; public int Productid { get { return productid; } set

C#学习笔记(八):扩展方法

还记得第一次使用DOTween时,发现缓动方法竟然是可以直接用Transform对象中调用到,当时就被震撼到了(那是还是C#小白一只).好了不多说了,今天来学习一下C#的这个特性——扩展方法. 扩展方法简介 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 这样我们可以方便的扩展对象方法而无需使用继承,同时也可以给密封类添加方法. 我们来看一个例子: 1 using System; 2 3 namespace Study 4 { 5 class

ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归.所以抛弃之前的那种事件响应的模型,抛弃服务器端控件也理所当然. 但是,如果手写Html标签效率又比较低,可重用度比较低.这时,我们该怎样来提高效率呢?首先,经过上篇我们知道可以通过ViewData传递数据,于是我们可以写出以下的Html代码: <input name="UserName&quo

[读书笔记]C#学习笔记五: C#3.0自动属性,匿名属性及扩展方法

前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好处, 下一遍会单独介绍Lambda表达式. 这篇主要包括的内容有: 自动属性,隐式类型,对象集合初始化,匿名类型,扩展方法. 下面一起来看下C#3.0 所带来的变化吧. 1,自动实现的属性在C#3.0之前, 定义属性时一般会像下面这样去编写代码: 1 class Person 2 { 3 //定义私