为什么要使用委托
需要将方法作为一个参数传递给另一个方法。
结合委托的概念,可以将以下代码:
static void Main(string[] args)
{
//三个需求
//1.将一个字符串数组中的每个元素都转换成大写
//2.将一个字符串数组中的每个元素都转换成小写
//3.将一个字符串数组中的每个元两边都加上双引号
string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
//ProsToUpper(names);
//ProsToLower(names);
AddQuot(names);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
/// <summary>
/// 转成大写
/// </summary>
/// <param name="name"></param>
public static void ProsToUpper(string[] name)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = name[i].ToUpper();
}
}
/// <summary>
/// 转成小写
/// </summary>
/// <param name="name"></param>
public static void ProsToLower(string[] name)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = name[i].ToLower();
}
}
/// <summary>
/// 加双引号
/// </summary>
/// <param name="name"></param>
public static void AddQuot(string[] name)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = "\"" + name[i] + "\"";
}
}
修改成:
//在类内部声明一个委托
//委托的语法:
//1、访问权限;2、delegate关键字;3、返回值类型;4、委托名;5、参数列表
public delegate string Str(string name);
static void Main(string[] args)
{
//三个需求
//1.将一个字符串数组中的每个元素都转换成大写
//2.将一个字符串数组中的每个元素都转换成小写
//3.将一个字符串数组中的每个元两边都加上双引号
string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
StrPro(names, StrToUpper);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
public static void StrPro(string[] name,Str del)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = del(name[i]);
}
}
public static string StrToUpper(string name)
{
return name.ToUpper();
}
public static string StrToLower(string name)
{
return name.ToLower();
}
public static string StrAddQuto(string name)
{
return "\"" + name + "\"";
}
委托概念
函数的签名必须和委托的签名一致。
签名:函数的返回值类型和参数类型,数量
//声明一个委托指向一个函数,必须和指向的函数签名相同
//签名是指返回值和传入的参数
public delegate void DelSayHi(string name);
class Program
{
static void Main(string[] args)
{
DelSayHi del = new DelSayHi(SayHiChinese);
del("张三");
Console.ReadKey();
}
public static void SayHiChinese(string name)
{
Console.WriteLine("吃了吗?" + name);
}
public static void SayHiEnglish(string name)
{
Console.WriteLine("Nice to meet you!" + name);
}
以下代码展示了委托如何将函数作为一个参数传递给另一个函数的。
//声明一个委托指向一个函数,必须和指向的函数签名相同
//签名是指返回值和传入的参数
public delegate void DelSayHi(string name);
class Program
{
static void Main(string[] args)
{
//将函数作为参数传递给另一个函数
Test("Lucy", SayHiEnglish);
Console.ReadKey();
}
public static void Test(string name,DelSayHi del)
{
del(name);
}
public static void SayHiChinese(string name)
{
Console.WriteLine("吃了吗?" + name);
}
public static void SayHiEnglish(string name)
{
Console.WriteLine("Nice to meet you!" + name);
}
匿名函数
当这个方法就执行一次的时候,可以不声明函数,写一个匿名函数。
还可以将第一个例子改成匿名函数。
代码如下:
//在类内部声明一个委托
//委托的语法:
//1、访问权限;2、delegate关键字;3、返回值类型;4、委托名;5、参数列表
public delegate string Str(string name);
static void Main(string[] args)
{
//三个需求
//1.将一个字符串数组中的每个元素都转换成大写
//2.将一个字符串数组中的每个元素都转换成小写
//3.将一个字符串数组中的每个元两边都加上双引号
string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
//匿名函数
//语法:1、delegate;2、参数列表;3、方法体。
StrPro(names, delegate(string name)
{
return name.ToUpper();
});
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
public static void StrPro(string[] name,Str del)
{
for (int i = 0; i < name.Length; i++)
{
name[i] = del(name[i]);
}
}
例子2:
public delegate void SayHiDel(string name);
static void Main(string[] args)
{
//delegate所声明的函数相当于是与SayHiDel签名一致的函数,可以直接赋值给这个委托
//然后通过声明的委托调用这个函数
SayHiDel del = delegate (string name)
{
Console.WriteLine("您好!" + name);
};
del("张三");
Console.ReadKey();
}
泛型委托
求任意数组中的最大值,用object类型声明数组,其实现源码如下:
//声明一个委托
public delegate int DelCompare(object o1, object o2);
static void Main(string[] args)
{
//求任意数组中的最大值
object[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine(GetMax(nums, Compare));
Console.ReadKey();
}
//比较两个数大小,将更大值赋值给max
public static object GetMax(object[] nums,DelCompare del)
{
object max = nums[0];
for (int i = 1; i < nums.Length; i++)
{
if(del(max,nums[i])<0)
{
max = nums[i];
}
}
return max;
}
//比较两个数的大小
public static int Compare(object o1,object o2)
{
int n1 = (int)o1;
int n2 = (int)o2;
return n1 - n2;
}
```
泛型委托的写法为:
//声明一个委托
public delegate int DelCompare<T>(T t1, T t2);
static void Main(string[] args)
{
//求任意数组中的最大值
int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine(GetMax<int>(nums, delegate(int n1,int n2)
{
return n1 - n2;
}));
Console.ReadKey();
}
//比较两个数大小,将更大值赋值给max
public static T GetMax<T>(T[] nums,DelCompare<T> del)
{
T max = nums[0];
for (int i = 1; i < nums.Length; i++)
{
if(del(max,nums[i])<0)
{
max = nums[i];
}
}
return max;
}
#lamda表达式
语法1:
public delegate void DelOne();
public delegate void DelTwo(string name);
public delegate string DelThree(string name);
static void Main(string[] args)
{
DelOne del = delegate () { };
DelOne del1 = () => { };
DelTwo del2 = (string name) => { };
DelThree del3 = (string name) => { return name; };
}
语法2:
List<int> list = new List<int>() { 1, 2, 3, 4, 55, 6, 7, 8, 9 };
//lamda表达式
list.RemoveAll(n => n > 4);
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.ReadKey();
“`