C-sharp委托和事件、集合
委托和事件
这里推荐一篇很好的入门文章:C# 中的委托和事件
委托
菜鸟教程
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。
委托(delegate),是一种数据结构,也是一种引用数据类型。委托主要用于回调机制(CallBack)和事件处理。
使用delegate类型的步骤如下:
声明delegate类型
定义委托所要代表的方法
创建委托实例,关联要代表的方法
调用委托实例
多重委托(在上述入门文章中已经提到过了)
例子,委托的基本操作:
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 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(); } } }