1、委托的定义。
委托实例可以封装属于可调用实体的方法
委托具有的特点:
.委托类似于c++函数指针,但它是类型安全的。
.委托允许将方法作为参数进行传递。
.委托可用于定义回调方法。
.委托可以链接在一起。例如,可以对一个时间调用多个方法。
.方法不需要与委托签名精确匹配???
委托可以认为是这样的对象,它具有相同签名和返回值类型的有序方法列表。
. 方法的列表成为调用列表(invocation list)
. 当委托被调用时,它调用列表中的每一个方法。
调用列表中的方法
由委托保存的方法可以来自任何类或结构
.返回值
.签名(包括ref和out修饰符)
调用列表中中的方法可以是实例方法或静态方法。
2.声明委托类型
[修饰符] delegate 返回类型 委托类型名(参数列表)
例如:
delegate void MyDel(int x);
这个声明的委托无返回值,参数为一个参数,类型为int.
委托对象定义了委托对象调用列表中允许的方法的形式。
注意:
委托和方法不同点。
.以delegate关键词开头。
.没有方法主体。
3.创建委托对象并实例化为调用的方法。
委托时引用类型,因此有引用和对象。
在委托对象声明之后,可以声明对象并创建类型的变量。
MyDel delVar;//创建委托对象的变量
MyDell dVar;
创建委托对象的两种方法:
第一种:使用带new运算符的对象创建表达式
。委托对象名
。一组圆括号,其中包含调用列表中第一个成员的方法的名字。方法可以是实例方法或静态方法。
MyTest mt=new MyTest();
使用实例方法创建委托对象
delVar =new MyDel(mt.MyInsMethod);
//使用静态方法创建委托对象。
dVar=new MyDel(MyTest.MyStaMethod);
第二种:快捷语法,因为方法名称和相应的委托类型之间有隐式转换
delVar=MyTest.MyStaMethod;
//声明测试类。
class MyTest
{
//实例方法
public void MyInsMethod(int i)
{
Console.WriteLine("我来自实例方法"+i);
}
//静态方法
public static void MyStaMethod(int m)
{
Console.WriteLine("我来自静态方法"+m-);
}
//第二个实例方法
public void MyInstance2(int y)
{
Console.WriteLine("我来自实例方法2"+y);
}
}
4. 组合委托
MyDel delA=mt.MyInsMethod;
MyDel delB=nt.MyInstance2;
MyDel delC=delA+delB;
这就是组合委托,这个运算最终会创建一个新的委托,其调用列表是两个操作数的委托调用列表的副本的
连接。
5. 为委托增加方法。
MyDel delA=mt.MyInsMethod;
delA +=mt.MyInstance2;
6. 从委托一处方法。
delA -=mt.MyInstance2;
移除方法应注意的事项。
(1)如果调用列表的方法有多个实例, -=运算符将从列表最后开始搜索,
并且移除第一个与方法匹配的实例。
(2)试图删除委托中不存在的方法没有效果。
(3)试图调用空委托会抛出异常。
(4)可以通过吧委托于null进行比较来判断委托的调用了列表是否为空。如果调用列表为空,则委托为空。
7.调用委托
调用方法一样来调用委托。
用于调用委托的参数将会用于调用调用列表中的每一个方法(除非有一个参数是输出参数)
一个方法可以再调用列表中出现多次。如果是这样,当委托被调用时,每次在列表中遇到这个方法时,都会被调用一次。
if(null!=delVar)
{
delVar(55);
}
8. 调用带返回值的委托。
如果委托有返回值,并且在调用列表中有一个以上的方法,会发生下面的情况。
(1)调用列表中最后一个方法的返回值就是委托调用返回的值。
(2)调用列表中所有其他方法的返回值都会被忽略。
例如:
delegate int DelAdd(int x);
static void Main()
{
MyAddClass mc = new MyAddClass();
DelAdd delAdd = mc.Add2;
delAdd += mc.Add3;
delAdd += mc.Add2;
Console.Write("value;{0}",delAdd(5));
}
class MyAddClass
{
public int Add2(int intValue)
{
return 2 + intValue;
}
public int Add3(int intValue)
{
return 3 + intValue;
}
}
输出结果为2. 因为正如上述所说,调用列表中最后一个方法的返回值就是委托调用返回的值,最后一个方法调用是 Add2方法。
9、 调用带引用参数的委托。
如果委托有引用参数,参数值会根据,调用列表中的一个或多个方法的返回值而改变,
在调用委托列表中的下一个方法时,参数的新值(不是初始值)会传给下一个方法。
例如:
delegate void DelRefAdd(ref int x);
static void Main()
{
MyAddRefClass mrc=new MyAddRefClass();
DelRefAdd delRef = mrc.Add2;
delRef += mrc.Add3;
delRef += mrc.Add2;
int i=5;
delRef(ref i);
Console.WriteLine("value,{0}",i);
}
class MyAddRefClass
{
public void Add2(ref int intValue)
{
intValue += 2;
}
public void Add3(ref int intValue)
{
intValue = 3 + intValue;
}
}
输出结果是:12
|