索引器提供一种特殊的方法,用于编写可使用方括号运算符调用的get和set访问方法,而不用传统的方法调用语法
public Photo this[int index] { get{} set{} }
注:仅有一个元素时没必要索引器进行检索,使用索引一般都是针对类的数组元素
using System; namespace BaseConsole { #region 照片 /// <summary> /// 照片 /// </summary> class Photo { string _title; public Photo(string title) { this._title = title; } public string Title { get { return _title; } } } #endregion #region 相册,即照片的集合 /// <summary> /// 相册,即照片的集合 /// </summary> class Album { //用于存储照片的数组 Photo[] photos; public Album(int capacity) { photos=new Photo[capacity]; } //传递的索引用于对照片数组进行检索 public Photo this[int index] { get { if(index<0||index>=photos.Length) { Console.WriteLine("索引无效"); return null; } return photos[index]; } set { if(index<0||index>=photos.Length) { Console.WriteLine("索引无效"); return; } photos[index] = value; } } //允许按Title检索照片 public Photo this[string title] { get { foreach(Photo p in photos ) { if(p.Title==title) { return p; } } Console.WriteLine("未找到"); return null; } } } #endregion class TestIndexer { static void Main(string[] args) { //创建一个容量为3的相册 Album friends = new Album(3); //创建3张照片 Photo first = new Photo("dong"); Photo second = new Photo("tom"); Photo third = new Photo("Mark"); //向相册加载照片 friends[0] = first; friends[1] = second; friends[2] = third; //按索引进行检索 Photo obj1photo=friends[2]; Console.WriteLine(obj1photo.Title); //按名称进行检索 Photo obj2photo=friends["dong"]; Console.WriteLine(obj2photo.Title); Console.ReadKey(); } } }
委托包含对方法而不是方法名称的引用,使用委托可以在运行时动态设定要调用的方法,不知道方法的名称,也可以调用方法,执行(或调用)一个委托将执行该委托引用的方法
委托要求方法的实现和委托必须具有相同数量/类型的参数,并有相同类型的返回值
使用委托的步骤
(1)定义委托
public delegate int call(int num1,int num2);
(2)实例化委托:使其指向(或引用)某个方法
要实例化委托,就要调用该委托的构造函数,并将要与该委托关联的方法(及其对象名称)作为其参数传递
(3)使用委托
调用委托意味着使用委托对方法进行实例化,调用委托不是调用委托的实现,而是调用与委托关联的方法的实现代码
using System; namespace BaseConsole { class Delegates { //委托定义 public delegate int Call(int num1,int num2); class Math { //乘法 public int Multiply(int num1,int num2) { return num1 * num2; } //除法 public int Divide(int num1,int num2) { return num1 / num2; } } class TestDelegates { static void Main(string[] args) { int result; //委托的对象 Call objcall; //Math 类的对象 Math objMath = new Math(); //实例化委托 objcall = new Call(objMath.Multiply); //调用委托 result = objcall(5,3); Console.WriteLine("结果为{0}",result); Console.ReadKey(); } } } }
使用委托的意义在于动态调用方法
C#中的事件允许一个对象将发生的事件或修改通知其他对象,将发生的事件通知其他对象的对象称为发行者。对象可以订阅事件,该对象称为订阅者。一个事件可以有一个或多个订阅者,事 件的发行者也可以是该事件的订阅者
C#中的事件处理步骤如下:
定义事件:定义事件时,发行者首先定义委托,然后根据该委托定义事件;委托限定了事件引发函数的类型,即函数的参数个数、类型以及函数的返回值类型
//定义一个委托 public delegate void delegateMe(); //定义一个事件 private event delegateMe eventMe;
订阅该事件: 订阅事件只是添加了一个委托,事件引发时该委托将调用一个方法
//objA方法订阅了事件eventMe eventMe +=new delegateMe(objA.Method);
引发事件
if(condition) { //引发eventMe事件 eventMe(); }
using System; namespace BaseConsole { class DelegateExample { #region Student类 class Student { //定义委托 public delegate void DelegateRegisterFinish(); //通过委托定义事件 public event DelegateRegisterFinish RegisterFinish; private string _name; public Student(string name) { _name = name; } public void Register() { Console.WriteLine("学生{0}进行注册",_name); if(RegisterFinish!=null) { //引发事件 RegisterFinish(); } } } #endregion class RegisterStudent { static void Main() { Console.Write("请输入注册学生的姓名:"); string studentName = Console.ReadLine(); Student student = new Student(studentName); //student_RegisterFinish函数订阅Student类的DelegateRegisterFinish事件 student.RegisterFinish += new Student.DelegateRegisterFinish(student_RegisterFinish); student.Register(); } private static void student_RegisterFinish() { Console.WriteLine("注册成功。"); Console.ReadLine(); } } } }