使用委托减少类之间的耦合

本文通过一个具体示例,介绍了如何利用C#中的委托来降低不同窗体类之间的耦合度,实现更灵活的对象间通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
据说C#的委托跟C++的函数指针很相似,C中的函数指针是n年前学习的,基本上对他不了解,这也是半路出家者在学习中所不得不承担的困难。关于委托,看过很多书和很多文章,反复下来,研读的次数大概不会少于15遍,但每次都似懂非懂。并不是像我这样的菜鸟不懂,就连高手往往也介于懂与不懂之间,仿佛如果昨天高手还理解委托的意义,经过一夜长眠,今天就不懂了。高手给菜鸟讲解的过程中,很容易就中了菜鸟的“圈套”,跌落到跟菜鸟一样的境界(我就这样对付过一个高手)。
如果说我现在已经理解了委托的意义,我想那基本上是不可能的,这可能需要长期的琢磨,好像是练习的是一种精神境界,而不是一种技术。但这几天做的一个事情,却使我对委托的好处有了进一步的了解。事情这这样的,假设有两个窗体Form1和Form2,Form1里面有一个DataGrid控件,Form2里有一个MapControl控件(ArcEngine),DataGird和MapControl分别用于盛放Feature的属性信息和图形,要求当选中DataGrid中一行的时候,MapControl中相应Feature高亮显示,当选中MapControl中的一个Feature时,DataGrid选中的行也要随之移动到相通的纪录上,就类似于ArcMap中,属性表的一行和地图窗口的Feature要一一对应的、互动的进行选择一样。
我们可以把Form2的一个对象作为Form1的一个成员变量,这样就可以通过Form1窗体来控制作为其成员的Form2实例,但是如果同样要求Form2控制Form1窗体中的DataGrid的话,就要把DataGrid作为参数传递给Form2窗体(当然你想传的更大的话,可以传Form1的实例)。这样设计的确不是一件好思路,因为这样导致了两个窗体类的互调,形成了极强的耦合。有什么办法可以减少这种耦合吗?这时委托就发挥作用了。我们仍然将Form2的实例作为Form1的成员变量,并通过调用该变量的函数,由DataGrid控制MapControl,但是我们并不把DataGrid作为参数传递给Form2,而是在Form2种定义一个共有委托实例,并在new Form2(在Form1中new的)的时候把这个委托实例初始化,即绑定到Form2里的一个方法上,然后在Form2中进行调用。方法如下:
 
类Form1的设计:
Public Class Form1
{
Private Form2 frmMapControl;
frmMapControl.dele = new deleContorlDataGrid(this.ControlDataGrid);//绑定到Form1的//ControlDataGrid方法上
 
private void ControlDataGrid(string strName)//通过Feature的name进行控制
{
………//控制DataGrid游标的位置
}
}
 
类Form2的设计
Public delegate void DelegateControl(string str);
Public Class Form2
{
Public DelegateControl dele;//定义共有委托实例
 
Private void ControlMapControl()
{
…..控制mapcontrol高亮显示Feature的代码段
}
 
}
 
 
这样,在使用的时候,可以在Form1直接通过成员frmMapControl的方法ControlMapControl()来控制Feature随着DataGrid不同的行进行高亮显示,也可以通过在Form2中用代理直接调用Form1里的ControlDataGrid()函数对DataGrid的游标位置进行控制。
这样设计的好处就是Form2不用使用Form1中的任何东西作参数进行初始化,减少了两个类之间的耦合。但是为了使得委托能够绑定到Form1中的方法,Form2的实例还是必须作为Form1 的成员。还有一个主意的地方是,代理的声明和初始化,不能在一个类里面,否则跟直接调用函数就没什么不同的了。
这个事情体现出代理的一个好处:减少类之间参数传递,减少耦合程度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值