C#中的委托与游戏中的运用
作者:网络转载 发布时间:[ 2016/3/31 11:19:10 ] 推荐标签:.NET 测试开发技术
1.什么是委托
在C/C++中,有函数指针的概念,即指向函数的指针。当我们调用该指针时,相当于调用了该指针所指向的函数,这是函数指针的一个作用,而他另一个作用是将自己作为其他函数的参数。
但是指针是直接访问内存单元的,程序员对指针的不恰当使用常常会引发错误。因此作为一门类型安全的语言,在一般情况下C#是不推荐使用指针的,比如使用函数指针作为参数时,你可以使用任何指针作为参数,因为他们都是32位的整型变量,不提供任何其他的信息,比如函数的参数个数,参数类型,返回值等。因此,在C#中有了委托的概念。
我们首先来看一个简单的委托实例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceDelegateTest
{
classprogram
{
delegatevoidMyDelegateTest(intx);
privatestaticvoidtest1(intx)
{
Console.WriteLine("输出平方"+(x*x));
}
privatestaticvoidtest2(intx)
{
Console.WriteLine("输出和"+(x+x));
}
staticvoidMain(string[]args)
{
inta=2;
MyDelegateTestdelegateTest;
delegateTest=newMyDelegateTest(test1);
//delegateTest=test1;
//delegateTest+=test1;
delegateTest+=test2;
delegateTest(a);
}
}
}
2.C#中委托的发展
上述是一个简单的委托例子,这里不再赘述具体的实现。基本来看委托和一个类的声明实现类似,首先以delegate关键字声明一个委托类型(这里注意声明的返回类型以及类型参数需要和后面对应的方法相同);然后声明和实例化一个委托类型变量,后调用该委托即可,注意添加到委托上的每个方法都会被调用,而我们并不关心这些方法是如何实现的。
在C#2.0之前,委托的定义都是通过上述步骤实现的,而在C#2.0中,引入了匿名方法的概念,其实是简化了委托的写法。比如我们之前需要写:
delegateTest=newMyDelegateTest(test1);
现在可以简化为:
delegateTest=delegate(intx){returnx*x;}
而在C#3.0中,又引入了函数式语言中的lambda表达式进一步简化:
delegateTest=x=>{returnx*x;}或直接x=>x*x;
在C#4.0又有了泛型委托,其实是定义的时候加个泛型限制:
delegateTMyDelegateTest<T>(Tx);
3.通过委托实现观察者模式
观察者模式是设计模式中一个很常见的模式,从生活中的例子来说,是对发布者进行关注的订阅者,在订阅者有更新时,会把消息推送给那些订阅者。在C#中可以用委托来实现观察者模式:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceObserverModel
{
classProgram
{
//------------------------------------------------------------------
//委托充当订阅者类
publicdelegatevoidDelegateSender(objectsender);
//------------------------------------------------------------------
//发布者类
publicclassPublisher
{
publicDelegateSenderSenderEvent;
publicstringInfo;
//--------------------------------------------------------------------
publicPublisher(stringinfo)
{
this.Info=info;
}
//-----------------------------------------------------------------------
//添加和删除订阅者
publicvoidAddObserver(DelegateSenderob)
{
SenderEvent+=ob;
}
publicvoidRemoveObserver(DelegateSenderob)
{
SenderEvent-=ob;
}
//----------------------------------------------------------------------
//发布者更新
publicvoidUpdate()
{
if(SenderEvent!=null)
{
SenderEvent(this);
}
}
}
//--------------------------------------------------------------------------
//具体订阅者类1
publicclassSubscriber
{
publicstringName;
publicSubscriber(stringname)
{
this.Name=name;
}
publicvoidDoSomething(Objectsender=null)
{
Console.WriteLine("订阅者1的操作");
}
}
//--------------------------------------------------------------------------
//具体订阅者类2
publicclassSubscriber2
{
publicstringName;
publicSubscriber2(stringname)
{
this.Name=name;
}
publicvoidDoSomething2(Objectsender=null)
{
Console.WriteLine("订阅者2的操作");
}
}
staticvoidMain(string[]args)
{
Publisherpublisher=newPublisher("发布者");
Subscribersub1=newSubscriber("订阅者1");
Subscriber2sub2=newSubscriber("订阅者2");
//添加订阅者
publisher.AddObserver(newDelegateSender(sub1.DoSomething));
publisher.AddObserver(newDelegateSender(sub2.DoSomething));
publisher.Update();
//移除订阅者
publisher.RemoveObserver(newDelegateSender(sub1.DoSomething));
publisher.Update();
Console.ReadLine();
}
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11