委托
(C#
高级编程笔记
)
p153
与C不同的是,.NET的委托是
类型安全的.C中的函数指针只不过是指向一个存储单元的指针,我们无法说出这个指针实际指向什么,而参数和返回类型就更无从知晓了.
实际上,”定义一个委托”是指”定义一个
新类”,委托的实现派生于System.MulticastDelegate, MulticastDelegate又派生于System.Delegate.
如何在C#中使用委托:
例1.
public
class
MyClass

...
{
public delegate string delegateTest(string dval1,string dval2);
public string ConnectString(string val1,string val2)

...{
return val1+val2;
}
public static void Main()

...{
MyClass mc = new MyClass();
delegateTest t = new delegateTest(mc.ConnectString);
Console.WriteLine(t("Hello"," China!"));
}
}
匿名方法
:
匿名方法定义委托时与前面没有区别,只是在实例化时,就不同了.匿名方法的
优点是减少了开销,方法仅在由
委托使用时才定义.
使用匿名方法要遵循的两个规则:
1、 在匿名方法中
不能使用跳转语句跳到该匿名方法体外;
2、 反之,匿名方法体外的语句也
不能跳转到匿名方法体内.
例2.
public
class
MyClass

...
{
public delegate string nonameTest(string dval1,string dval2);//匿名委托
public static void Main()

...{
nonameTest nonameT = delegate(string val1,string val2)//注意实例化时的区别

...{
return val1+val2;
}; //注意分号
Console.WriteLine(nonameT("Hello"," China"));
Console.ReadLine();
}
}
例3中,将委托的实例放在数组中是可以的.该数组的每一个元素都执行不同的操作,这样我们就可以在循环中调用不同方法了.
例3.
public
class
MyClass

...
{
public static double doubleCal(double val) //静态

...{
return val * 2;
}
public static double squareCal(double val) //静态

...{
return val * val;
}
public delegate double MathCal(double val);
public static void Main()

...{

MathCal[] uMath = new MathCal[]...{new MathCal(doubleCal),new MathCal(squareCal)};//委托数组
for(int i = 0;i<uMath.Length;i++)

...{
Console.WriteLine(uMath[i](4));
}
Console.ReadLine();
}
}
BubbleSorter
示例
P161
冒泡算法
public
class
MyClass

...
{
public int[] Sort(int[] arr)

...{
int[] array = arr;
for(int i = 0;i < array.Length -1;i++)

...{
for(int j = i+1;j < array.Length;j++)

...{
if(array[j]<array[i])

...{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
public static void Main()

...{
MyClass mc = new MyClass();

int[] arr = ...{0,2,5,3,7,8};
arr = mc.Sort(arr);
for(int i=0;i<arr.Length;i++)

...{
Console.Write(arr[i]);
}
Console.ReadLine();
}
}
自己写的一个委托例子,只是用来显示用法
自总结:
使用到委托函数的特点,看ShowFinded,它将参数1(一个类数组)传递进第二个(委托)参数(其实是方法)中进行处理.我感觉就是如果要在
函数中处理函数,那需要使用到委托(就是回调,就是函数指针嘛)
例4.
public
class
MyClass

...
{
public static int cnt = 0;
public delegate int delegateFind(object[] id,string area);//委托(按地区查找)
//此函数处理过程:将类数组当参数传给委托dFind(其实就是进入Find),得到查询人数,再输出.
public static void ShowFinded(object[] id,delegateFind dFind,string area)//静态(输出地区分部人数)

...{
int showCnt = dFind(id,area);
Console.WriteLine(area+"人共有"+showCnt+"名.");
}
public int Find(object[] id,string area)

...{
for(int i = 0; i < id.Length; i++)

...{
if(((Identify)id[i]).area == area)

...{
MyClass.cnt ++;
}
}
return MyClass.cnt;
}
public static void Main()

...{

Identify[] id = new Identify[]...{ new Identify("张三",22,"河北"),new Identify("李四",25,"江苏"),
new Identify("王五",20,"山东"),new Identify("小强",27,"江苏"),
new Identify("阿扁",23,"火星"),new Identify("布什",13,"火星") };
MyClass mc = new MyClass();
delegateFind dFind = new delegateFind(mc.Find);
MyClass.ShowFinded(id,dFind,"江苏"); //主处理函数,静态
}
}

public
class
Identify

...
{
public string name;
public int age;
public string area;
public Identify(string name,int age,string area)

...{
this.name = name;
this.age = age;
this.area = area;
}
}
多播委托
调用多播委托,就可以
按顺序连续调用多个方法(注意,如果用于
事件,则是
无序的),为此,多播委托的
返回值必然是
void.
例5.
public
class
MyClass

...
{
public static void doubleCal(double val) //返回值void

...{
Console.WriteLine("double_operate value is "+val * 2);
}
public static void squareCal(double val) //返回值void

...{
Console.WriteLine("square_operate value is "+val * val);
}
public delegate void MathCal(double val); //返回值void
public static void Main()

...{
MathCal mc = new MathCal(doubleCal);
mc += new MathCal(squareCal); // +=
// MathCal mc1 = new MathCal(doubleCal);
// MathCal mc2 = new MathCal(squareCal);
// MathCal mc = mc1 + mc2; // +
mc(3);
Console.ReadLine();
}
}
//
output:
//
double_operate value is 6
//
square_operate value is 9