题
有人可以将代表的含义分解为简单、简短、简洁的解释,其中包含目的和一般利益吗?我尝试着去思考这个问题,但就是无法理解。
解决方案
在最简单的可能方面,它本质上是一个指针的方法。
您可以保存委托类型(就像你有一个可以容纳一个int类型为int变量)的变量。您可以执行该方法的委托点,通过简单地调用您的变量的功能等。
这可以让你具有不同的功能,就像你可能有变量数据。您的对象可以接受来自其他对象的代表和调用它们,而无需定义所有可能的功能本身。
这时候你要根据用户指定的标准的对象做的事情是非常方便的。例如,过滤基于用户定义的真/假表达式列表。您可以让用户指定委托函数作为过滤器用来对评估每个项目。
其他提示
我有一个函数:
public long GiveMeTwoTimesTwo()
{
return 2 * 2;
}
此功能吸收。如果我想3 * 3?
public long GiveMeThreeTimesThree()
{
return 3 * 3;
}
太多打字。我懒!
public long SquareOf(int n)
{
return n * n;
}
我SquareOf
函数并不关心n
是什么。它将为传入任何n
正常运行。它不知道数量n
到底是什么,但它的不的知道n
是一个整数。不能传递到"Haha not an integer"
SquareOf
。
这里的另一个功能:
public void DoSomethingRad()
{
int x = 4;
long y = SquareOf(x);
Console.WriteLine(y);
}
相反,它的名字,DoSomethingRad实际上并没有做任何事情弧度。然而,它确实写SquareOf(4),其是16.我们可以改变它被闷少?
public void DoSomethingRad(int numberToSquare)
{
long y = SquareOf(numberToSquare);
Console.WriteLine(y);
}
DoSomethingRad
显然还是相当失败。但至少现在我们可以在一些传递给方,所以不会写,每次16。 (这将写1,或4,或9,或16,或... ZZZZ仍然有点儿镗孔)。
这会是很好,如果有改变发生了什么传入数量的方式也许我们并不想将其平方。也许我们想向立方体,或从69(数字随机选择从我的头)中减去。
在进一步的检查,却仿佛SquareOf
的唯一部分DoSomethingRad
关心的是,我们可以给它一个整数(numberToSquare
),它给了我们一个long
(因为我们在y
把它的返回值和y
是一个long
)。
public long CubeOf(int n)
{
return n * n * n;
}
public void DoSomethingLeet(int numberToSquare)
{
long y = CubeOf(numberToSquare);
Console.WriteLine(y);
}
请参阅DoSomethingLeet
如何相似是DoSomethingRad
?如果只存在在的行为的(DoX()
)传递的方式,而不是仅仅的数据的(int n
)...
因此,如果我们想要写一个数的平方,我们可以DoSomethingRad
,如果我们想要写一个数的立方体,我们可以DoSomethingLeet
。因此,如果我们想写从69减去的数字,做我们必须做的另一种方法,DoSomethingCool
?不,因为那需要太多该死很多键入(更重要的是,它通过改变我们的计划只是一个方面阻碍了我们改变有趣的行为能力)。
因此,我们在抵达:
public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
long y = doSomething(doSomethingToMe);
Console.WriteLine(y);
}
我们可以通过编写这个调用此方法:
Radlicious(77, SquareOf);
Func<int, long>
是一种特殊的委托。它存储接受整数和吐出long
s行为。我们不知道它指向的方法是要与任何给定的整数我们通过做;我们所知道的是,无论发生什么事,我们会得到一个long
回来。
我们没有给任何参数SquareOf
因为Func<int, long>
描述的行为的,而不是数据。调用Radlicious(77, SquareOf)
只是给Radlicious SquareOf
(“我取号,并返回其方”)的一般行为,不是SquareOf
会做任何的具体的整数。
现在,如果你已经明白我在说什么,那么你已经有一个调升了我,因为我自己真的不明白这些东西。
<强> * END ANSWER,BEGIN WANDERING白痴* 强>
我的意思是,它似乎像int
s可能被视为只是真钻的行为:
static int Nine()
{
return 9;
}
这就是说,之间是什么数据和行为的线出现模糊,用了通常被视为数据简单地钻孔屁股行为。
当然,人们可以想像超“有趣”的行为,即由各种不同的抽象参数,但需要一吨的信息,以便能够调用它。如果它需要我们提供源代码,这将编译并运行我们呢?
好了,那么我们的抽象似乎已经得到了我们所有的回到原点的一种方式。我们有这样的行为抽象它要求我们的整个程序的源代码,以确定它会做。这是完全不确定的behavioR:该功能可以做的任何的,但它必须具备的所有的决定它做什么。在另一方面,完全确定的行为,如Nine()
,不需要任何额外的信息,但不能做以外的任何其他回报9
。
还等什么?我不知道。
有趣的是,没有人提到的代表团的主要好处之一 - 当你意识到继承不是灵丹妙药,通常产生的问题比它解决它的最好子类。它是许多设计模式的基础上,最显着的策略图案。
一个代表实例是一种方法的参考。他们是有用的原因是,你可以创建一个依赖于特定的方法对一种类型的特定实例的委托。委托实例可以让您即使在要调用的方法的对象已经离开你的词汇范围,调用在那个特定的实例方法。
有这样的委托实例最常见的用途是支持的回调<概念/ A>在语言级别。
它只是引用的方法。他们有很大的使用与跨线程的工作。
下面是一个例子右出的我的代码。
//Start our advertisiment thread
rotator = new Thread(initRotate);
rotator.Priority = ThreadPriority.Lowest;
rotator.Start();
#region Ad Rotation
private delegate void ad();
private void initRotate()
{
ad ad = new ad(adHelper);
while (true)
{
this.Invoke(ad);
Thread.Sleep(30000);
}
}
private void adHelper()
{
List<string> tmp = Lobby.AdRotator.RotateAd();
picBanner.ImageLocation = @tmp[0].ToString();
picBanner.Tag = tmp[1].ToString();
}
#endregion
如果你没有使用委托你就无法crossthread并调用Lobby.AdRotator功能。
像其他人所述,委托是对函数的参考。一个更有益的用途(IMO)的是事件。当您注册一个事件您注册事件调用的函数,代表是完美的完成这个任务。
在最基本的方面,一个委托只是包含一个函数(一个引用)的一个变量。因为他们让你周围的传递函数的变量没有任何顾虑“其中”功能实际上是来自于委托是有用的。
这是需要注意的重要的,当然,当它在一个变量被捆绑功能不被复制;它只是作为参考约束。例如:
class Foo
{
public string Bar
{
get;
set;
}
public void Baz()
{
Console.WriteLine(Bar);
}
}
Foo foo = new Foo();
Action someDelegate = foo.Baz;
// Produces "Hello, world".
foo.Bar = "Hello, world";
someDelegate();
用最简单的术语来说,执行方法的责任被委托给另一个对象。假设某个国家的总统去世,美国总统应该出席葬礼并表达哀悼。如果美国总统无法前往,他会将这一责任委托给副总统或国务卿。
代码中也是如此。委托是一种类型,它是能够执行方法的对象。
例如。
Class Person
{
public string GetPersonName(Person person)
{
return person.FirstName + person.LastName;
}
//Calling the method without the use of delegate
public void PrintName()
{
Console.WriteLine(GetPersonName(this));
}
//using delegate
//Declare delegate which matches the methods signature
public delegate string personNameDelegate(Person person);
public void PrintNameUsingDelegate()
{
//instantiate
personNameDelegate = new personNameDelegate(GetPersonName);
//invoke
personNameDelegate(this);
}
}
使用委托对象 personNameDelegate 调用 GetPersonName 方法。或者,我们可以使用 PrintNameUsingDelegate 方法将委托作为参数。
public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
{
pnd(person);
}
优点是如果有人想将名字打印为姓氏_名字,他/她只需将该方法包装在 personNameDelegate 中并传递给此函数即可。无需进一步更改代码。
代表在以下方面特别重要:
- 活动
- 异步调用
- LINQ(作为 lambda 表达式)
如果你要委派任务给某人,委托会是谁接收工作的人。
在编程,这是对的代码实际上知道如何做块的参考。通常,这是一个指向函数或方法,该方法将处理一些项目。
在绝对是最简单的话来说,我可以想出是这样的:一位代表将迫使工作的负担为一类非常知道该怎么做的手中。把它看成是不希望长大后能像他哥哥完全,但仍然需要他的指导和订单孩子。相反,继承了哥哥的所有方法(即子类)的,他只是让他的弟弟做的工作或小兄弟做一些事情,需要采取由大哥的动作。当你陷入议定书的线条,大哥定义什么是绝对必要的,否则他可能会给你灵活选择你想要让他在某些事件做(即非正式和正式的协议,如在Objective-C中概述)是什么。
这个概念的绝对好处是,你并不需要创建一个子类。如果你想要的东西加入行列,服从命令,当一个事件发生,委托允许开发类来保存它的手,如果需要发号施令。