簡體   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