1、delegate委托、Action<T>、Fun<T>
delegate:把方法当做参数进行传递;
//定义委托类型及参数
delegate int TestDelegate(int x, int y);
public void Test()
{
//实例化一个委托
TestDelegate dele = new TestDelegate(Add);
//调用委托
Console.WriteLine(dele(1, 2));
Console.ReadKey();
}
public int Add(int a, int b)
{
return a + b;
}
2、Action<T>泛型委托,有参数但是没有返回值
Action 委托至少0个参数,至多16个参数,无返回值。
Action 表示无参,无返回值的委托。
Action<int,string> 表示有传入参数int,string无返回值的委托。
public void ActionTest(string key, Action<string> oFunc)
{
oFunc.Invoke(key);
}
public static void aa(this Action act)
{
try
{
act.Invoke();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
3、Fun<T>泛型委托,有返回值,有返回类型的委托
Func 至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。
Func<int> 表示没有输入参数,返回值为int类型的委托。
Func<object,string,int> 表示传入参数为object, string ,返回值为int类型的委托。
Func<object,string,int> 表示传入参数为object, string, 返回值为int类型的委托。
场景1【Student示例】
public static class abcd
{
static List<Student> studentList = new List<Student>();
public static void FuncTest(string key, Func<object> oFunc)
{
oFunc.Invoke();
}
/// <summary>
/// 不用每次都循环遍历
/// </summary>
public static void bb()
{
studentList.TestWhere(s => s.age > 30);
}
public static List<Student> TestWhere(this List<Student> list, Func<Student, bool> func)
{
List<Student> students = new List<Student>();
foreach (var stu in list)
{
if (func.Invoke(stu))
{
students.Add(stu);
}
}
return students;
}
}
场景2【Stock示例,Controller控制器示例】
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
namespace WebAPI.Controllers
{
[Route("api/func_test")]
[ApiController]
public class FuncTestController : ControllerBase
{
[HttpGet("get1")]
public ActionResult Get1()
{
var result = GetWhere(Init(), s => s.id > 7);
return Ok(result);
}
public List<StockDto> GetWhere(List<StockDto> data, Func<StockDto, bool> func)
{
List<StockDto> list = new List<StockDto>();
foreach (var item in data)
{
if (func.Invoke(item))
{
list.Add(item);
}
}
return list;
}
public List<StockDto> Init()
{
List<StockDto> list = new List<StockDto>();
for (int i = 1; i < 10; i++)
{
list.Add(new StockDto
{
id = i,
stock_name = $"stock_name_{i}",
category_id = i,
});
}
return list;
}
}
}
场景3【泛型,迭代器】
public static class CustomLinqExtend
{
public static List<T> TestWhere<T>(this List<T> list, Func<T, bool> func)
{
List<T> tList = new List<T>();
foreach (var item in list)
{
if (func.Invoke(item))
{
tList.Add(item);
}
}
return tList;
}
/// <summary>
/// 迭代器
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IEnumerable<T> EnumerableWhere<T>(this List<T> list, Func<T, bool> func)
{
foreach (var t in list)
{
if (func.Invoke(t))
{
yield return t;
}
}
}
}
场景4【数据库访问】
Func<TObject, bool>是委托(delegate)
Expression<Func<TObject, bool>>是表达式
Expression编译后就会变成delegate,才能运行。
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Repository
{
public class BaseRepository<T, D> : IRepository<T> where T : DoBase where D : DbContext
{
public BaseRepository(D context)
{
Context = context;
}
public D Context { get; }
public bool IsExist(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().AsNoTracking().Any(exp);
}
public T Max(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().AsNoTracking().Where(exp).Max();
}
public int GetCount(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().AsNoTracking().Where(exp).Count();
}
public IQueryable<T> Find(Expression<Func<T, bool>> exp = null)
{
return Filter(exp).AsNoTracking();
}
public T GetModel(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().AsNoTracking().FirstOrDefault(exp);
}
public T FindLocal(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().Local.FirstOrDefault(exp.Compile());
}
public T FindSingleTracking(Expression<Func<T, bool>> exp)
{
return Context.Set<T>().FirstOrDefault(exp);
}
public IQueryable<T> FindTracking(Expression<Func<T, bool>> exp = null)
{
return Filter(exp);
}
public PagerDto<T> GetPagerList(Expression<Func<T, bool>> whereExpression, int pageIndex, int pageSize, Expression<Func<T, object>> orderByExpression = null)
{
PagerDto<T> list = new PagerDto<T>();
list.RecordTotal = Context.Set<T>().Where(whereExpression).Count();
list.Data = Context.Set<T>().Where(whereExpression).OrderBy(orderByExpression).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
list.PageTotal = (int)Math.Ceiling(list.RecordTotal / (double)pageSize);
return list;
}
public async Task<PagerDto<T>> GetPageList(Expression<Func<T, bool>> whereExpression, int pageIndex, int pageSize, Expression<Func<T, object>> orderByExpression = null)
{
PagerDto<T> list = new PagerDto<T>();
list.RecordTotal = await Context.Set<T>().Where(whereExpression).CountAsync();
list.Data = await Context.Set<T>().Where(whereExpression).OrderBy(orderByExpression).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
list.PageTotal = (int)Math.Ceiling(list.RecordTotal / (double)pageSize);
return list;
}
private IQueryable<T> Filter(Expression<Func<T, bool>> exp)
{
var dbSet = Context.Set<T>().AsQueryable();
if (exp != null)
dbSet = dbSet.Where(exp);
return dbSet;
}
}
}
*
*
*
*
*
*
*
*
*
*
*
*