一. 简介
委托(Delegate)是一种引用类型,可以看作是函数指针,用来封装一个或多个方法,并允许将这些方法作为参数传递给其他方法。委托可以用于实现事件和回调机制,提供了一种灵活的方式来处理方法的组合和调用。
最直观的理解就是把定义的委托类型当成是一个变量,使用一个方法给这个委托类型的变量赋值。
LINQ(Language Integrated Query)是C#语言中的一个查询语言扩展,用于方便地进行数据查询和操作。LINQ 可以对不同类型的数据源进行查询,包括集合(List、Array等)、数据库、XML等。它提供了一种统一的语法和操作符,使得我们可以使用类似 SQL 的语句来过滤、排序、分组和投影数据。
二. 原始的委托使用
声明委托类型-->声明委托变量-->给委托对象赋值-->使用委托
namespace 委托_Lambda_LINQ
{
// 声明4种委托类型,分别为:
// 无参无返回值
public delegate void AddDle1();
// 有参无返回值
public delegate void AddDle2(int i);
// 无参有返回值
public delegate int AddDle3();
// 有参有返回值
public delegate int AddDle4(int i);
internal class Program
{
static void Main(string[] args)
{
//分别声明这四种委托类型变量,并赋值
AddDle1 addDle1 = Add1;
AddDle2 addDle2 = Add2;
AddDle3 addDle3 = Add3;
AddDle4 addDle4 = Add4;
// 分别执行调用这几个委托,两种调用方式效果是一样的
addDle1.Invoke();
addDle2.Invoke(1);
int a = addDle3();
int b = addDle4(1);
}
public static void Add1()
{
}
public static void Add2(int i)
{
int a = i;
}
public static int Add3()
{
return 0;
}
public static int Add4(int i)
{
return i + 10;
}
}
}
三. 委托简化 Action和Func的使用
微软为了简化委托的声明,直接内置了一个无返回值的Action泛型委托类型,和有返回值的Func泛型委托类型。
使用委托时就可以直接定义成Action或Func类型,不需要提前声明委托类型了。
namespace 委托_Lambda_LINQ
{
internal class Program
{
static void Main(string[] args)
{
Action addDle1 = Add1;
Action<int> addDle2 = Add2;
Func<int> addDle3 = Add3;
Func<int, int> addDle4 = Add4;
// 分别执行调用这几个委托,两种调用方式效果是一样的
addDle1.Invoke();
addDle2.Invoke(1);
int a = addDle3();
int b = addDle4(1);
}
public static void Add1()
{
}
public static void Add2(int i)
{
int a = i;
}
public static int Add3()
{
return 0;
}
public static int Add4(int i)
{
return i + 10;
}
}
}
四. 委托赋值使用匿名方法
namespace 委托_Lambda_LINQ
{
internal class Program
{
static void Main(string[] args)
{
Action addDle1 = delegate ()
{
Console.WriteLine("我是匿名方法Add1");
};
Action<int> addDle2 = delegate (int i)
{
Console.WriteLine("我是匿名方法Add1");
};
Func<int> addDle3 = delegate ()
{
Console.WriteLine("我是匿名方法Add3");
return 0;
};
Func<int, int> addDle4 = delegate (int i)
{
Console.WriteLine("我是匿名方法Add4");
return i + 10;
};
// 分别执行调用这几个委托,两种调用方式效果是一样的
addDle1.Invoke();
addDle2.Invoke(1);
int a = addDle3();
int b = addDle4(1);
}
//public static void Add1()
//{
// Console.WriteLine("我是常规方法Add1");
//}
//public static void Add2(int i)
//{
// int a = i;
// Console.WriteLine("我是常规方法Add2");
//}
//public static int Add3()
//{
// Console.WriteLine("我是常规方法Add3");
// return 0;
//}
//public static int Add4(int i)
//{
// Console.WriteLine("我是常规方法Add4");
// return i + 10;
//}
}
}
五. Lambda表达式
5.1 由匿名方法过度到使用=>, 省略delegate关键字,参数类型和括号
namespace 委托_Lambda_LINQ
{
internal class Program
{
static void Main(string[] args)
{
Action addDle1 = () =>
{
Console.WriteLine("我是匿名方法Add1");
};
Action<int> addDle2 = (i) =>
{
Console.WriteLine("我是匿名方法Add1");
};
Func<int> addDle3 = () =>
{
Console.WriteLine("我是匿名方法Add3");
return 0;
};
Func<int, int> addDle4 = (i) =>
{
Console.WriteLine("我是匿名方法Add4");
return i + 10;
};
// 分别执行调用这几个委托,两种调用方式效果是一样的
addDle1.Invoke();
addDle2.Invoke(1);
int a = addDle3();
int b = addDle4(1);
}
}
}
5.2 如果方法内只有一行代码,可以省略大括号和return
namespace 委托_Lambda_LINQ
{
internal class Program
{
static void Main(string[] args)
{
Action addDle1 = () => Console.WriteLine("我是匿名方法Add1");
Action<int> addDle2 = i => Console.WriteLine("我是匿名方法Add1");
Func<int> addDle3 = () => 0;
Func<int, int> addDle4 = i => i + 10;
// 分别执行调用这几个委托,两种调用方式效果是一样的
addDle1.Invoke();
addDle2.Invoke(1);
int a = addDle3();
int b = addDle4(1);
}
}
}
六. LINQ语句中的委托
namespace 委托_Lambda_LINQ
{
internal class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>() {1,2,3,4,5,6,7 };
// 常规的Linq语句,实际上Where的参数就是一个Func委托
list = list.Where(p=> p < 5).ToList();
//将这个参数的Func委托进行还原
Func<int, bool> func = p => p < 5;
list = list.Where(func).ToList();
//继续还原
Func<int, bool> func1 = (p) => { return p < 5; };
list = list.Where(func1).ToList();
//继续还原
Func<int, bool> func2= delegate (int p) { return p < 5; };
list = list.Where(func2).ToList();
//继续还原
Func<int, bool> func3 = Select;
list = list.Where(func3).ToList();
//继续还原
Func<int, bool> func4 = Select;
list = MyWhere(list, func4).ToList();
//继续还原
list = MyWhere(list);
}
public static List<int> MyWhere(List<int> ints, Func<int, bool> func4)
{
var list = new List<int>();
foreach (int i in ints)
{
if (func4.Invoke(i))
{
list.Add(i);
}
}
return list;
}
public static List<int> MyWhere(List<int> ints)
{
var list = new List<int>();
foreach (int i in ints)
{
if (Select(i))
{
list.Add(i);
}
}
return list;
}
public static bool Select(int p)
{
return p < 5;
}
}
}