zoukankan      html  css  js  c++  java
  • 【ABP杂烩】Extensions后缀扩展方法

    1.Extensions介绍

    扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。 对于用 C#、F# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法没有明显区别。

    详细见官方文档:扩展方法(C# 编程指南)

    2.语法介绍

    * 需要写在一个静态类中 
    * 必须是一个静态方法 
    * 通过第一个参数和this关键字指定扩展的目标类型 
    * 不同类型的扩展方法不一定要写在同一个类中

    3.事例介绍

     在ABP框架原中会发现在很多地方带有Extensions的类,其主要作用是在不改变原有接口或类的基础上扩展自定义的方法,从而方便使用,如QueryableExtensions类是对IQueryable进行扩展,里面添加了分页PageBy、条件判断WhereIf方法,代码如下:

    ​
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using Abp.Application.Services.Dto;
    
    namespace Abp.Linq.Extensions
    {
        /// <summary>
        /// Some useful extension methods for <see cref="IQueryable{T}"/>.
        /// </summary>
        public static class QueryableExtensions
        {
            /// <summary>
            /// Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
            /// </summary>
            public static IQueryable<T> PageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
            {
                if (query == null)
                {
                    throw new ArgumentNullException("query");
                }
    
                return query.Skip(skipCount).Take(maxResultCount);
            }
    
            /// <summary>
            /// Used for paging with an <see cref="IPagedResultRequest"/> object.
            /// </summary>
            /// <param name="query">Queryable to apply paging</param>
            /// <param name="pagedResultRequest">An object implements <see cref="IPagedResultRequest"/> interface</param>
            public static IQueryable<T> PageBy<T>(this IQueryable<T> query, IPagedResultRequest pagedResultRequest)
            {
                return query.PageBy(pagedResultRequest.SkipCount, pagedResultRequest.MaxResultCount);
            }
    
            /// <summary>
            /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
            /// </summary>
            /// <param name="query">Queryable to apply filtering</param>
            /// <param name="condition">A boolean value</param>
            /// <param name="predicate">Predicate to filter the query</param>
            /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
            public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
            {
                return condition
                    ? query.Where(predicate)
                    : query;
            }
    
            /// <summary>
            /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
            /// </summary>
            /// <param name="query">Queryable to apply filtering</param>
            /// <param name="condition">A boolean value</param>
            /// <param name="predicate">Predicate to filter the query</param>
            /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
            public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
            {
                return condition
                    ? query.Where(predicate)
                    : query;
            }
        }
    }
    
    ​

    如上所述,对IQueryable扩展后,可以像调用原生方法一样,使上层的调用感受不到区别和不用做过多的操作,方便对第三方的库进行扩展,从而增加自定义需求,有效提高项目的开发效率。调用代码如下:

     public async Task<PagedResultDto<ProjectListDto>> GetProjects(GetProjectsInput input)
            {
                var query = _projectRepository.GetAll();
                query = query
                    .WhereIf(!input.Name.IsNullOrWhiteSpace(), item => item.Name.Contains(input.Name))
                    .WhereIf(!input.Address.IsNullOrWhiteSpace(), item => item.Address.Contains(input.Address))
                    .WhereIf(!input.ResponbleDepart.IsNullOrWhiteSpace(), item => item.ResponbleDepart.Contains(input.ResponbleDepart))
                    .WhereIf(!input.Type.IsNullOrWhiteSpace(), item => item.Type.Contains(input.Type))
                    .WhereIf(input.ProjectDateStart.HasValue, item => item.StartTime >= input.ProjectDateStart)
                    .WhereIf(input.ProjectDateEnd.HasValue, item => item.EndTime <= input.ProjectDateEnd)
                    .WhereIf(input.ReportDateStart.HasValue, item => item.ReportTime >= input.ReportDateStart)
                    .WhereIf(input.ReportDateEnd.HasValue, item => item.ReportTime <= input.ReportDateEnd);
    
    
                var projectCount = await query.CountAsync();
    
                var projects = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync();
    
                var projectListDtos = ObjectMapper.Map<List<ProjectListDto>>(projects);
    
                return new PagedResultDto<ProjectListDto>(
                    projectCount,
                    projectListDtos
                    );
            }
    

      

  • 相关阅读:
    自定义asp.net mvc Filter 过滤器
    基于委托的C#异步编程的一个小例子 带有回调函数的例子
    ASCII、Unicode和UTF-8编码的区别
    Specification模式的一个不错的示例代码
    codesmith 自动生成C# model 实体模板
    Quartz.NET 实现定时任务调度
    FtpHelper类匿名获取FTP文件
    crc32 根据字符串获取校验值
    机器学习能做什么
    RunHelper,一个为跑步而设计的开源的android app
  • 原文地址:https://www.cnblogs.com/OlderGiser/p/9957401.html
Copyright © 2011-2022 走看看