实验 第十二章 委托和事件(一)
一 实验目标:
1 理解指针函数和委托的区别,利用委托能实现类型安全性
2 能够掌握设计委托来实现方法回调功能
3 掌握使用数组来调用委托
二 实验内容
1、 定义如下的委托类型:
public delegate string middle(string id);
请设计一个People类,该类有_id和_name两字段成员,有一个公有方法成员,其方法描述为:
public string getName(string id)
{
if(_id==id)
return _name;
else
return null;
}
要求上述委托封装该方法,并能正确回调该方法,根据其编号_id输出其姓名。
2、 测试程序,写出结论
using System;
public delegate string Delegt1(int i);
public delegate void Delegt2();
public delegate void Delegt3(int j);
public class ClasA
{
int privt; //私有数据
protected string [] Ary;
public int getPri
{
get
{
return privt;
}
}
public Delegt2 FromClasB; //在类中声明委托
public Delegt3 ChangeA;//在类中声明委托
public ClasA(){}
public ClasA(int k,string [] a) //构造函数
{
privt=k;
Ary=a;
}
public string MethodA(int i)
{
return Ary[i]+" is in ClasA.";
}
}
public class ClasB
{
int privt;
public int getPri
{
get
{
return privt;
}
}
public void ChangePri(int jj)
{
privt=jj;
}
public string MethodB(int i)
{
return i.ToString()+" is in ClasB.";
}
public void WhoTell()
{
Console.WriteLine("Who can tell me?");
}
public static void WhatDelegt() //静态方法
{
Console.WriteLine("What is the delegate?");
}
}
public class Test
{
public static void CalDelegts(Delegt1 dg,int i) //委托可以作为方法的参数
{
Console.WriteLine(dg(i));
}
public static void Main()
{
string [] Ss={"aa","bb","cc"};
ClasA CA=new ClasA(0,Ss);
ClasB CB=new ClasB();
Delegt1 gfunc = new Delegt1(CA.MethodA); //创建委托,与ClasA中方法关联
Console.WriteLine(gfunc(1));
Delegt2 g2func=new Delegt2(ClasB.WhatDelegt); //创建委托,与静态方法关联
g2func();
CA.FromClasB=new Delegt2(CB.WhoTell); //ClasA中的委托与ClasB中的方法关联
CA.FromClasB(); //调用该委托
CA.FromClasB=new Delegt2(ClasB.WhatDelegt); //ClasA中的委托与ClasB中静态方法关联
CA.FromClasB();
Delegt1 [] Mydlgt =new Delegt1[2]; //利用数组依次调用委托
Mydlgt[0]=new Delegt1(CA.MethodA);
Mydlgt[1]=new Delegt1(CB.MethodB);
foreach(Delegt1 dl in Mydlgt) CalDelegts(dl,2);
CA.ChangeA=new Delegt3(CB.ChangePri); //ClasA的委托与ClasB中方法关联
CA.ChangeA(7); //方法试图改变私有数据
Console.WriteLine(CA.getPri); //改变了ClasA对象的私有数据?
Console.WriteLine(CB.getPri); //改变了ClasB对象的私有数据?
}
}
① 委托能实现安全类型调用的原因
② 委托所封装的方法与具体类有关吗
③ 该程序是如何使用数组来实现委托的,写出其实现的部分代码。
④ 测试上述程序
3、编写一个实现委托多播的完整程序,比较单播委托和多播委托的异同。
using System;
public delegate double CalcuAGS();
public class Student
{
double totleScore;
int totleCredit;
string studName;
string [] courseName;
double [] score;
int [] credit;
public Student(){}
public Student(string nam, string [] cors, double [] scor, int [] crdt)
{
studName=nam;
courseName=cors;
score=scor;
credit=crdt;
}
public double AddScore()
{
totleScore=0;
foreach(double d in score) totleScore+=d;
return totleScore;
}
public int AddCredit()
{
foreach(int i in credit)totleCredit+=i;
return totleCredit;
}
public double AveScore()
{
totleScore=0.0;
return ( AddScore()/(score.Length));
}
public double AveWeiScore()
{
double stemp=0.0;
int itemp=0;
for(int j=0; j<score.Length;j++)
{
stemp+=score[j]*credit[j];
itemp+=credit[j];
}
return stemp/itemp;
}
} bu hui
public class Test
{
public static void Main()
{
string [] ss=new string[]{"C", "C++", "C#"};
double [] dd=new double []{89.0, 97.0, 83.5};
int [] ii=new int []{6, 6, 8};
Student Stud=new Student("John", ss, dd, ii);
CalcuAGS ADS=new CalcuAGS(Stud.AddScore);
CalcuAGS AVS=new CalcuAGS(Stud.AveScore);
CalcuAGS AWS=new CalcuAGS(Stud.AveWeiScore);
ADS+=AVS;
ADS+=AWS;
Console.WriteLine("ADS+AVS+AWS: "+ADS());
ADS-=AWS;
Console.WriteLine("ADS+AVS: "+ADS());
ADS-=AVS;
Console.WriteLine("ADS: "+ADS());
}
}