C#1所搭建的核心基础(一)-委托
委托在某种程度上提供了间接的方法。换言之,不需要直接指定一个行为,而是将这个行为用某种方式“包含”在一个对象中。这个对象可以象其他任何对象那样使用。在这个对象中,可以执行封装的行为。可以将委托类型看做只定义了一个方法的接口,将委托的实例看做实现了那个接口的一个对象。
委托的4个基本条件:
1)声明委托类型;
2)必须有一个方法包含了要执行的代码;
3)必须创建一个委托实例;
4)必须调用(invoke)委托实例。
1.声明委托类型
委托类型实际上只是参数类型的一个列表以及一个返回类型。它规定了类型的实例能表示的操作。以如下方式声明一个委托类型。
delegate void StringProcessor(string input);
这里的重点是StringProcessor其实是一个类型。它有方法,可以创建它的实例,并将引用传递给实例。
2.为委托实例的操作找到一个恰当的方法
找到(或者写)一个方法,它能做我们想做的事情,同时具有和委托类型相同的签名。
来看看以下StringProcessor实例的5个备选的方法签名:
void PrintString(string x)
void PrintInteger(int x)
void PrintTwoString(string x, string y)
int GetStringLength(string x)
void PrintObject(object x)
我们来看,第一个方法完全符合要求,所以可以用它创建一个委托实例。第二个方法虽然也有一个参数但不是string类型,所以不兼容StringProcessor。第三个方法参数数量不匹配,所以不兼容。第四个方法有正确的参数列表,但是返回类型不是void(如果委托类型有返回类型,方法的返回类型也必须与之匹配)。第五个方法比较有趣,任何时候调用一个StringProcessor实例,都可以调用具有相同的参数的PrintObject方法,这是由于string是从object派生的。
3.创建委托实例
既然已经有了一个委托类型和一个有正确签名的方法,接着可以创建委托类型的一个实例,指定在调用委托实例时就执行该方法。至于具体用什么形式的表达式来创建委托实例,取决于操作使用实例方法还是静态方法。如果操作是静态方法,指定类型名称就可以了。如果操作时实例方法,就需要先创建类型(或者它的派生类型)的一个实例。这和平时调用方法是一样的。
假定PrintString是StaticMethods类型中的一个静态方法,在InstanceMethods类型中是一个实例方法。下面是创建一个StringProcessor实例的两个例子:
StringProcessor proc1, proc2;
proc1=new StringProcessor(StaticMethods.PrintString);
InstanceMethods instance=new InstanceMethods();
prce2=new StringProcessor(instance.PrintString);
4.调用委托实例
这是很简单的事情(仅对同步调用而言)-调用一个委托实例的方法就可以了。这个方法本身被称为Invoke。在委托类型中,这个方法以委托类型的形式出现,并且具有与委托类型的声明中所指定的相同的参数列表和返回类型。调用Invoke会执行委托实例的操作,向它传递在调用Invoke时指定的任何参数。让我们看下下图更好的理解:
下面来看一个完整的代码:
using System;
//声明委托类型
delegate void StringProcessor(string input);
class Person
{
string name;
public Person(string name) { this.name = name; }
//声明兼容的实例方法
public void Say(string message)
{
Console.WriteLine("{0}说:{1}", name, message);
}
}
class Background
{
//声明兼容的静态方法
public static void Note(string note)
{
Console.WriteLine("({0})",note);
}
}
class SimpleDelegateUse
{
static void Main()
{
Person jon = new Person("Jon");
Person Tom = new Person("Tom");
//创建3个委托实例
StringProcessor jonsVoice, tomsVoice, background;
jonsVoice = new StringProcessor(jon.Say);//实例方法
tomsVoice = new StringProcessor(Tom.Say);//实例方法
background = new StringProcessor(Background.Note);//静态方法
//调用委托实例
jonsVoice("Hello,World!");
tomsVoice.Invoke("欢迎观临我的博客!");
background("版权所有爱智旮旯!");
Console.Read();
}
}
效果如图: