C-sharp委托和事件、集合

委托和事件

这里推荐一篇很好的入门文章:C# 中的委托和事件

委托

菜鸟教程

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

委托(delegate),是一种数据结构,也是一种引用数据类型。委托主要用于回调机制(CallBack)和事件处理。

使用delegate类型的步骤如下:

  1. 声明delegate类型
  2. 定义委托所要代表的方法
  3. 创建委托实例,关联要代表的方法
  4. 调用委托实例

多重委托(在上述入门文章中已经提到过了)

例子,委托的基本操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo01
{
// 声明委托类型
public delegate void MyDelegate1();
public delegate void MyDelegate2(string msg);
public delegate int MyDelegate3(int n);
public delegate void MyDelegate4();
public delegate void MyDelegate5();
class Program
{
public static void M1()
{
Console.WriteLine("M1:这是无参数无返回值的方法");
}
public static void M2(string msg)
{
Console.WriteLine("M2:这是有参数无返回值的方法,参数为{0}", msg);
}
public static int M3(int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum = sum + i;
}
Console.WriteLine("M3:这是有参数有返回值的方法,参数为{0},返回值为{1}", n, sum);
return sum;
}
public static void M4()
{
Console.WriteLine("M4:这是无参数无返回值的方法");
}
public static void M5()
{
Console.WriteLine("M5:这是无参数无返回值的方法");
}
public static void M6()
{
Console.WriteLine("M6:这是无参数无返回值的方法");
}

static void Main(string[] args)
{
Console.WriteLine("下面是普通的委托与方法的绑定");
// 委托与方法的绑定
MyDelegate1 myDelegate1 = M1; // new MyDelegate1(M1);
myDelegate1(); // 效果为调用了M1方法

MyDelegate2 myDelegate2 = M2;
myDelegate2("Hello"); // // 效果为调用了M2方法,"Hello"为M2中的参数

MyDelegate3 myDelegate3 = M3;
myDelegate3(5); // // 效果为调用了M3方法,5为M3中的参数

Console.WriteLine("下面是多重委托的绑定");
// 多重委托
MyDelegate4 myDelegate4 = M4; // 第一个委托用 =
myDelegate4 += M5; // 后面的多重委托用+=
myDelegate4 += M6; // 后面的多重委托用+=
myDelegate4(); // 会按照绑定顺序依次执行M4,M5,M6
// 多重委托的移除
myDelegate4 -= M5; // 移除多重委托用-=
myDelegate4(); // 会按照绑定顺序依次执行M4,M6

Console.WriteLine("下面是使用Lambda表达式的委托");
// 使用Lambda表达式的委托
// Lambda表达式是一个可用于创建委托的匿名函数
// 在lambda运算符 => 的左侧指定输入参数,在右侧放置表达式或语句
MyDelegate5 myDelegate5 = new MyDelegate5(()=>
{
Console.WriteLine("Lambda:这是无参数无返回值的方法");
});
myDelegate5();
MyDelegate2 myDelegate2_1 = new MyDelegate2((msg) =>
{
Console.WriteLine("Lambda:这是有参数无返回值的方法");

});
myDelegate2_1("Lambda_Hello");

Console.ReadLine();
}
}
}

注意上述的Lambda表达式。

内置委托

  • Action 无参数无返回值的委托
  • Action<T> 有参数无返回值的委托(T为参数)
  • Func<T,T> 有参数有返回值的委托(前面的T为参数,最后一个T为返回值)

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo02
{
class Program
{
static void Main(string[] args)
{
// 内置委托
Action action1 = new Action(() =>
{
Console.WriteLine("这是无参数无返回值的方法");
});
action1();

Action<string> action2 = new Action<string>((msg) =>
{
Console.WriteLine("这是有参数无返回值的方法,参数为{0}", msg);
});
action2("Hello");

Func<int, int> func = new Func<int, int>((n) =>
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum = sum + i;
}
Console.WriteLine("M3:这是有参数有返回值的方法,参数为{0},返回值为{1}", n, sum);
return sum;
});
func(10);

Console.ReadLine();
}
}
}

事件

菜鸟教程

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。

C# 中使用事件机制实现线程间的通信。

  • 触发事件的对象——发送方
  • 被通知的对象——接收方

事件是类的方法成员之一。在C#中事件通过委托来实现。

例子,模拟场景:听到铃声后、学生做好上课准备

  1. 声明委托类型
  2. 声明事件的发布者
  3. 声明事件的接受者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo03
{
// 声明委托类型
public delegate void MyDelegate(string msg);

// 声明事件的发布者
class SchoolRing
{
public event MyDelegate myEvent;
// 自定义方法用于触发事件
public void Ring(string msg)
{
myEvent(msg);
}
}

// 声明事件的接受者
class Student
{
public void PerPare(string str)
{
Console.WriteLine("听到{0},同学准备上课了",str);
}
}

// 模拟场景:听到铃声后、学生做好上课准备
class Program
{
static void Main(string[] args)
{
SchoolRing schoolRing = new SchoolRing();
Student student = new Student();
schoolRing.myEvent += student.PerPare; // 将方法绑定到事件
schoolRing.Ring("上课铃响了");
Console.ReadLine();
}
}
}

集合

菜鸟教程

  • 集合可以有效管理多个数据
  • 集合可以根据程序运行的需要进行动态地增长和收缩
  • 常用集合类:ArrayList、Hashtbale、Queue、Stack

ArrayList

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo04
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
// 添加集合元素
list.Add(666);
list.Add(3.14);
list.Add("hello");
list.Add(true);
int[] arr = { 1, 2, 3, 4, 5 };
list.AddRange(arr); // 添加多个数据

// 插入集合元素
list.Insert(3, "world"); // 3表示插入索引位置
int[] arr2 = { 2, 3, 3 };
list.InsertRange(0,arr2); // 插入多个数据

// 修改集合元素
list[1] = 222;

// 删除集合元素
list.Remove(true); // 从 ArrayList 中移除第一次出现的指定对象。
list.RemoveAt(1); // 移除 ArrayList 的指定索引处的元素
list.RemoveRange(3, 4); // 3表示索引开始的位置,删除4个元素
//list.Clear(); // 从 ArrayList 中移除所有的元素。

Console.WriteLine("集合中元素的个数为{0}", list.Count);
// 遍历集合
Console.Write("集合的元素为:");
for (int i = 0; i < list.Count; i++)
{
Console.Write(list[i]+",");
}
Console.ReadLine();
}
}
}

具体的相关方法菜鸟教程中都有提到,可自行查看。

泛型集合

C#非泛型集合和泛型集合的超级详解(转)

List,例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo05
{
class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>() { 3, 5, 1, 9, 7 };
Console.WriteLine(list.Max());
Console.WriteLine(list.Min());
Console.WriteLine(list.Average());
Console.WriteLine(list.Sum());
List<int> list1 = list.Where(n => n > 5).ToList(); // 获取list中大于5的列表(使用了Lambda表达式)
Console.Write("list1的元素为:");
foreach (var item in list1)
{
Console.Write(item + ",");
}
Console.Write("排序前list的元素为:");
foreach (var item in list)
{
Console.Write(item + ",");
}
Console.WriteLine();
list.Sort();
Console.Write("排序后list的元素为:");
foreach (var item in list)
{
Console.Write(item + ",");
}
Console.ReadLine();
}
}
}

C# List用法 List介绍

Dictionary,例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace demo06
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, int> dic = new Dictionary<string, int>(); // 键值对
dic.Add("小明", 100);
dic.Add("小王", 70);
dic.Add("小红", 90);
//dic.Add("小明", 90); // 程序运行报错
if (dic.ContainsKey("小明")) // 先判断小明是否已存在
{
Console.WriteLine("小明键已存在,无法添加!");
}
else
{
dic.Add("小明", 98);
}
// 修改(通过键来索引值)
dic["小王"] = 80;
// 遍历Dictionary集合的方法有三种,遍历键、遍历值、直接遍历键值对(和python类似)所以这里只给出直接遍历键值对
foreach (var item in dic)
{
Console.WriteLine("键:{0}==>值{1}", item.Key, item.Value);
}

Console.ReadLine();
}
}
}