四.把一个方法赋值给一个委托变量的这种机制,可以实现把方法当做参数进行传递,如果一个方法,其参数是一个委托,则调用该方法时,就可以把与该委托格式一样的方法传给形参.下面的代码以List集合类型里面的RemoveAll方法为例: [C] 纯文本查看 复制代码 List<int> list = new List<int>();
list.Add(123);
list.Add(123);
list.Add(234);
list.Add(123);
list.RemoveAll((int a) =>
{
if (a == 123)
{
return true;
}
return false;
});
foreach (int s in list)
{
Console.WriteLine(s);
}
先看一下RemoveAll方法的原型,public int RemoveAll(Predicate<T> match);进入到API里面,看到其形参是一个委托类型,原型为:public delegate bool Predicate<in T>(T obj);T为泛型类型占位符,上面的代码中list中用的是int类型,故此委托里面的T也为int,委托的原型为返回值为bool类型,参数为int类型,在调用方法时,用的是lambda表达式,参数是int类型的a,方法体里面的返回值类型为bool类型,a会遍历集合里面的所有元素,只要等于123,返回为true,就会把123从集合里面删除掉,遍历完一遍后,把集合里面的123全部删除了,输出的结果只有234了.
五.委托可以绑定多个方法这种特性,可以用在设计模式上面,下面有个Unity的一个Demo,先看一下截图:
屏幕快照 2015-09-15 下午10.13.47.png (100.63 KB, 下载次数: 0) 下载附件 前天 22:45 上传 工程运行前,场景中有四个带颜色的物体,中间是一个小球,然后移动小球,与四个物体中的任何一个碰撞后,再按下空格键,则把碰撞过的物体颜色改为蓝色.效果图如下:
屏幕快照 2015-09-15 下午10.14.11.png (19.95 KB, 下载次数: 0) 下载附件 前天 22:45 上传 其主要的思想就是:在移动的小球的脚本里面,定义了一个接口类型的变量,在其它四个物体的脚本都继承接口,接口类里面有一个委托属性,只有get方法,然后四个物体的脚本都继承该接口,实现接口里面的属性,委托属性的返回值是其脚本里面的方法,其格式和定义的委托格式一样,当移动的小球与四个物体碰撞后,就把所碰撞物体脚本组件赋值给移动小球脚本组件里面的接口变量,然后再调用相对应的委托变量所返回的方法,把相对应的物体的颜色改变即可.下面是代码: 脚本一是绑定在四个带有颜色物体上的脚本组件[C] 纯文本查看 复制代码 using UnityEngine;
using System.Collections;
public class EnemyHurt : MonoBehaviour,IEventInterface
{
public HurtDelegate hurtdelegate {
get {
return Hurt;
}
}
public void Hurt ()
{
//把物体材质的颜色变成黑色,代表已死亡
transform.renderer.material.color = Color.blue;
}
} 下面两个脚本是加到移动小球上面的: 脚本二.
[C] 纯文本查看 复制代码 using UnityEngine;
using System.Collections;
//此脚本是用来控制小球移动的
public class Move : MonoBehaviour
{
//小球移动的速度
public float speed = 3.0f;
void Update ()
{
//得到横竖虚拟轴的值
float hor = Input.GetAxis ("Horizontal");
float vec = Input.GetAxis ("Vertical");
//小球的移动
transform.position += new Vector3 (hor, 0, vec) * Time.deltaTime * speed;
}
} 脚本三:
[C] 纯文本查看 复制代码 using UnityEngine;
using System.Collections;
public class Boom : MonoBehaviour
{
//定义一个接口的属性,由于敌人继承了该接口,只需要把子类的对象赋值给该接口变量即可执行子类里面的方法
public IEventInterface eventInterface{ get; set; }
//碰撞检测,当小球与四个物体发生碰撞时,
void OnCollisionEnter (Collision other)
{
//如果碰撞物体的父物体不为空并且父物体的名字是Enemies时
if (other.transform.parent != null && other.transform.parent.name == "Enemies") {
//接口变量指向子类的对象,就会调用所指向的子类里面的委托.
this.eventInterface = other.transform.GetComponent<EnemyHurt> ();
}
}
// Update is called once per frame
void Update ()
{
//当按下空格键时,调用委托,实际上调用的就是接口变量所指向的子类里面的委托,而
//其委托又返回的是子类里面的方法
if (Input.GetKeyDown (KeyCode.Space)) {
this.eventInterface.hurtdelegate ();
}
}
}
脚本四:是一个公有的文件其它脚本组件可以引用该文件里面的接口
[C] 纯文本查看 复制代码 using UnityEngine;
using System.Collections;
//声明一个委托
public delegate void HurtDelegate ();
//创建一个接口
public interface IEventInterface
{
//声明一个委托属性
HurtDelegate hurtdelegate{ get; }
}
以下是Unity场景里面的各物体之间的父子关系图:
屏幕快照 2015-09-15 下午10.27.44.png (12.33 KB, 下载次数: 0) 下载附件 前天 22:45 上传 以上就是关于委托的应用,由于书写时间仓促,有什么问题还请各位大神多多指教.
|