繁体   English   中英

将匿名/ lambda函数传递给没有参数的无效委托? [C#]

[英]Passing anonymous/lambda functions to void delegates with no parameters? [C#]

我一直在探索C#委托和匿名/ lambda函数,并且对它们如何交互存在一些疑问。 据我了解,简单的委托对象可以具有预定义的返回和参数类型,并且可以将具有相同返回/参数类型的任何命名函数分配给委托。

但是,就我而言,我一直在研究一种游戏,其中玩家可以将多个命令加入他们的commandList中。 在添加到命令列表后的某个时刻,命令最终由播放器执行。

我开始通过为每个命令(AttackCommand,HealCommand等)创建特定的子类来实现这一点,但后来发现在制作各种新命令的原型时,这繁琐 我认为,出于测试目的,使用成员委托创建CustomCommand类非常酷,这样我就可以匿名定义和传递函数,并快速迭代新的游戏设计思路。

public class CustomCommand : Command {

    public delegate void CommandDelegate();
    private CommandDelegate func;

    public CustomCommand( CommandDelegate del ){
        func = del;
    }

    public Execute(){
        func();
    }
}

然后,Player具有定义匿名函数并使用它来构造CustomCommand的方法。 但是,令我有些困惑的是,该方法的参数似乎可以存储在CustomCommand的委托中:

//inside Player class..
//command to steal gold from a target!
public CreateCustomCommand( Player targetPlayer ){
    CustomCommand.CommandDelegate anonCommand = delegate()
    {
         //Steals up to amount passed..
         int goldToSteal = targetPlayer.StealGold(25);
         gold += goldToSteal;
    };

    CustomCommand newCommand = new CustomCommand( anonCommand );
    commandList.Enqueue( newCommand );
}

//Command is automatically executed later..

我已经试过了这段代码,不仅可以编译,而且还可以工作。 金钱从目标中被窃取并添加到源播放器中。 我很高兴它能起作用,但是我不确定幕后到底发生了什么,这让我有些不安。

这是我很难理解的内容:

在(Player)的CreateCustomCommand方法中, 黄金在范围内,因为它是Player类的成员 ,而targetPlayer在范围内,因为它是一个参数 ..但是这些东西如何包装在匿名函数中,以及传递给另一个对象内部的一个空的,无参数的委托,并且仍然有效? 这里发生了什么事? 匿名函数的创建是否存储对它包含的所有对象的引用?

与将命名函数分配给具有匹配的返回/参数类型的委托相比,这似乎非常灵活,但是是否存在主要缺点或陷阱? 而且,该技术是否与任何特定的设计模式或编程方法有关(或部分与之相关)?

如果我正确地理解了这一点,那是可行的,因为匿名函数会使用闭包 闭包是可以捕获创建它们的可变环境的代码块(请参阅:Lambda表达式中的变量作用域)

因此,由于CreateCustomCommand方法定义了一个匿名函数(闭包),因此该匿名函数捕获并维护了对CreateCustomCommand范围内变量的访问。

感谢@HansPassant为我指出正确的方向!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM