代表与活动

ser*_*hio 8 .net c# vb.net events delegates

当一个班级不能(或不应该)做某事时,事件或代表可能是一个解决方案.

class President
  Event AskedQuestion(QuestionEventArgs)
  Delegate GetAnswerToQuestion

class Scientist
  AnswerToQuestion()

// delegate approach
myPresident.GetAnswerToQuestion = AddressOf myScientist.AnswerToQuestion
// called once myPresident need it

// event approach
myScientist.AnswerToQuestion(questionEventArgs) Handles President.AskedQuestion
{ 
   // executed once president asked a question
}
Run Code Online (Sandbox Code Playgroud)

在这里,在委托的方式方法,科学家直接由总统类使用,一旦发生一个校长提出了一个问题,而科学家反应,因此有一个答案.

在.NET Framework代码中,我没有观察到,但直接使用了委托.直接使用它是错误的,如果,为什么?

Eri*_*ert 9

直接使用它是错误的,如果,为什么?

不,这没错.

以下是我对此的看法.委托字段是事件,因为字符串字段是属性.也就是说,你可能有:

class Car
{
    private string modelName;
    public string ModelName { get { return this.modelName; } }
    ...
Run Code Online (Sandbox Code Playgroud)

模型名称在逻辑上是汽车的属性.当有人问你驾驶什么样的车并且你说"福特福克斯"时,你正在描述汽车的属性.你不认为"福特福克斯"是一个"领域"或"字符串",你会认为它是一种汽车的名称.在计算机程序中,字符串字段只是存储名称的实现细节.该属性可以是一个字符串,也可以是一个枚举,或者其他什么; 关键在于逻辑上,汽车有型号名称,而不是字符串字段.

事件和代表的方式是一样的.汽车可以有一个"爆炸"事件(也许你正在写一个视频游戏!),爆炸事件是由一个委托类型的领域实现的.爆炸是汽车逻辑上的事情; 委托字段是实现事件的机制.

那么直接使用代表是"错误的"吗?不,当然不.只是直接使用字符串是"错误的".有时您需要操作非属性的字符串,有时您需要操作非事件的委托.

诀窍是编写明确区分机械流程和业务流程的代码.如果您发现将大量字符串逻辑与属性逻辑混合在一起,或者将大量委托操作与事件混合在一起,那么您可能会考虑尝试将机制代码与业务代码分开一些,以便它更容易看出哪个是哪个.


Fre*_*örk 2

框架中大量使用了委托。LINQ 就是一个明显的例子:

var result = someCollection.Where(input => input.MatchesSomeCriteria);
Run Code Online (Sandbox Code Playgroud)

Where接受具有特定签名的委托,调用该委托以确定是否在结果中包含某个项目。最常见的用法是上面所示的lambda方法,但您也可以传递一个方法:

string[] nums = new[]{ "1", "2", "3"};
int sum = nums.Select(int.Parse).Sum();
Run Code Online (Sandbox Code Playgroud)

int.ParseSelect与本例中所需的委托签名( Func<string,int>) 匹配,因此将为 中的每个字符串调用它nums

通常,当直接使用委托时,它们被视为将使用它们的方法调用的输入。尽管在某些地方它们是消费者状态的一部分(HttpListener例如具有一些委托类型的属性),但它们并不多。