我在哪里使用代表?[关闭]


Answers:


33

委托是一种定义了一种特定方法的命名类型。正如类定义为它定义的给定类型的对象列出所有成员一样,委托也为其定义的类型的方法列出方法签名。

基于此语句,委托是函数指针,它定义该函数的外观。

谓词是在现实世界中应用委托的一个很好的例子。在链接的示例中,您会注意到Array.Find使用数组进行搜索,然后使用谓词处理要查找的内容的条件。在这种情况下,它将通过与谓词签名匹配的ProductGT10方法。


154

“学习C#3.0:掌握C#3.0的基础知识”所述

一般情况: 当国家元首去世时,美国总统通常没有时间亲自参加葬礼。相反,他派遣了一名代表。该代表通常是副总统,但有时没有副总裁,总统必须派遣其他人,例如国务卿甚至第一夫人。他不想将自己的授权“硬连线”给一个人。他可以将这一责任委托给能够执行正确的国际协议的任何人。

总统预先确定将下放什么责任(参加葬礼),传递什么参数(慰问,友好的言语)以及他希望获得的价值(善意)。然后,当他担任总统职务时,他会在“运行时”将一个特定的人分配给该委托职责。

在编程场景中: 您经常会遇到需要执行特定操作的情况,但是您事先不知道要调用哪个方法甚至对象。

例如: 一个按钮可能不知道需要通知哪些对象。您无需将按钮连接到特定对象,而是将按钮连接到委托,然后在程序执行时将该委托解析为特定方法。


1
为什么不简单地使用匿名函数/ lambdas呢?
Pacerier,2014年

5
@Pacerier这是一个较晚的响应,您可能已经找到了答案,但是为了其他发现此问题的读者:匿名函数是委托的一种。
安东尼

10
@ Anthony + Pacerier:不一致的方法不是委托。匿名方法是一段代码。委托是指向该段代码的指针。如果没有委托指向您,则不能有一个匿名方法,否则它将永远不会被调用。Lambda是运算符,用于构造Lambda表达式。Lambda表达式主要导致不一致的方法,该方法将由...委托指向。
马丁·穆尔德

愚蠢的我,但是如果我不知道按下按钮时的用途,我只会创建一个If ElseIf语句。我说我傻。
JustJohn

如果先引入Lambda,则C#2.0中引入的@Pacerier匿名方法和C#3.0中引入的Lambda永远不会是匿名方法,甚至不会委托!
AminM

18

泛型列表的委托的一种常见用法是通过Action委托(或其匿名等效项)来创建一行foreach操作:

myList.Foreach( i => i.DoSomething());

我还发现谓词委托在搜索或修剪列表中非常有用:

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

我知道您说不需要代码,但是我发现通过代码表达其用处更加容易。:)


13

将事件绑定到事件处理程序通常是您对委托的首次介绍...您甚至可能不知道自己在使用它们,因为委托被包装在EventHandler类中。


5

如果您有兴趣了解在实际代码中如何使用Delegate模式,那么在Mac OS X上,Cocoa就是您的最佳选择。Cocoa是Apple在Mac OS X下进行编程的首选UI工具包,并且在Objective C中进行了编码。旨在使每个UI组件都可以通过委托而不是子类化或其他方式进行扩展。

有关更多信息,我建议在此处查看Apple对代表的看法。


5

我有一个使用win32 Python的项目。

由于各种原因,某些模块使用odbc.py来访问数据库,而其他模块使用pyodbc.py。

当两种模块都需要使用某个功能时,就会出现问题。它有一个连接对象作为参数传递给它,但是随后它必须知道是使用dbi.dbiDate还是使用datetime来表示时间。

这是因为odbc.py期望作为SQL语句中的值,日期为dbi.dbiDate而pyodbc.py期望为datetime值。

进一步的麻烦是,由odbc.py和pyodbc.py创建的连接对象不允许设置其他字段。

我的解决方案是通过委托类包装odbc.odbc(...)和pyodbc.pyodbc(...)返回的连接对象,该委托类包含所需的时间表示函数作为额外字段的值,并委托对原始连接对象的所有其他字段请求。


5

我和您有相同的问题,请转到该网站寻求答案。

显然,即使我略过了该线程上的示例,也并没有更好地理解它。

我现在阅读以下内容,对代表有很大的帮助: http : //www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

对于新用户而言,这似乎更为明显,因为与使用POST / GET(QueryString)的ASP.NET网站相比,传递表单值要复杂得多。

基本上,您定义了一个以“ TextBox text作为参数的委托。

// Form1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

//摘要:定义委托,实例化新的Form2类,将funData()函数分配给委托,将textBox传递给委托。显示表格。

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

//摘要:只需将TextBox txtForm1作为参数(在委托中定义),然后将标签文本分配给textBox的文本。

我希望这对代表有所启发:) ..


Form2类方法需要命名为funData(而不是passData),或者Form1函数分配需要命名为frm.passData(而不是frm.funData)。
ethan

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.