如何制作一个指向另一个动作 C# 的动作?

我在 C# 中遇到了一些意想不到的行为。我基本上是在尝试将一个操作分配给另一个操作的引用,以便我可以在以后订阅/取消订阅引用操作的方法。我不想知道实现引用操作的类。


问题是,应该指向我想听的动作的动作似乎实际上并没有指向它。我认为每当提出引用的操作时它都会引发,但显然情况并非如此。


我可能对代表有一些误解。有人可以告诉我我做错了什么吗?我想要实现的目标有解决方案吗?


我感谢任何回应!


public class WaitForActionProcess : IProcess

{

    public Action Finished { get; set; }

    Action actionHandler;


    public WaitForActionProcess(ref Action action)

    {

        actionHandler = action;

    }


    public void Play()

    {

        actionHandler += RaiseFinished;

    }


    public void RaiseFinished()

    {

        actionHandler -= RaiseFinished;


        if(Finished != null)

        {

            Finished();

        }

    }

}

使用示例:


public class ReturnToMainMenuFrame : TutorialEventFrame

{

    [SerializeField]

    TutorialDialogueData dialogueData;


    [SerializeField]

    PointingArrowData arrowData;


    [SerializeField]

    TutorialDialogue tutorialDialogue;


    [SerializeField]

    PointingArrow arrow;


    [SerializeField]

    MainView mainView;


    public override void StartFrame()

    {

        frameProcesses.Add(new ShowPointToUIProcess(arrow, arrowData));

        frameProcesses.Add(new ShowDialogueProcess(tutorialDialogue, dialogueData));

        frameProcesses.Add(new WaitForActionProcess(ref mainView.OnViewShown));

        frameProcesses.Add(new HideDialogueProcess(tutorialDialogue, this));

        frameProcesses.Add(new HidePointToUIProcess(arrow,this));

        base.StartFrame();

    }


}


森栏
浏览 146回答 2
2回答

Qyouu

简答c# - 如何制作指向另一个动作的动作?你不能。动作是委托,委托是不可变的。应该指向我想听的动作的动作似乎实际上并没有指向它。那是因为delegates是不可变的。即使您传递了一个ref委托,当您执行分配时,您也会创建一个副本。代表strings就是这样。public WaitForActionProcess(ref Action action){&nbsp; &nbsp; // assignment creates a copy of a delegate&nbsp; &nbsp; actionHandler = action;}例子这是为您准备的小提琴,可以进一步演示。public class Program{&nbsp; &nbsp; static Action action1;&nbsp; &nbsp; static Action actionHandler;&nbsp; &nbsp; public static void Main()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; WaitForActionProcess(ref action1);&nbsp; &nbsp; }&nbsp; &nbsp; public static void WaitForActionProcess(ref Action action)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // this is still a reference to action1&nbsp; &nbsp; &nbsp; &nbsp; action += Both;&nbsp; &nbsp; &nbsp; &nbsp; // assignment creates a copy of a delegate&nbsp; &nbsp; &nbsp; &nbsp; actionHandler = action;&nbsp; &nbsp; &nbsp; &nbsp; // action is still a reference to action1&nbsp; &nbsp; &nbsp; &nbsp; // but actionHandler is a *copy* of action1&nbsp; &nbsp; &nbsp; &nbsp; action += OnlyAction1;&nbsp; &nbsp; &nbsp; &nbsp; actionHandler += OnlyActionHandler;&nbsp; &nbsp; &nbsp; &nbsp; action();&nbsp; &nbsp; &nbsp; &nbsp; // Both&nbsp; &nbsp; &nbsp; &nbsp; // OnlyAction1&nbsp; &nbsp; &nbsp; &nbsp; actionHandler();&nbsp; &nbsp; &nbsp; &nbsp; // Both&nbsp; &nbsp; &nbsp; &nbsp; // OnlyAction2&nbsp; &nbsp; }&nbsp; &nbsp; public static void Both()=> Console.WriteLine("Both");&nbsp; &nbsp; public static void OnlyAction1() => Console.WriteLine("OnlyAction1");&nbsp; &nbsp; public static void OnlyActionHandler() => Console.WriteLine("OnlyActionHandler");}可能的解决方法使用 aList<Action>代替。这是一个 Fiddle。using System;using System.Collections.Generic;public class Program{&nbsp; &nbsp; static List<Action> action1 = new List<Action>();&nbsp; &nbsp; static List<Action> actionHandler;&nbsp; &nbsp; public static void Main()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; WaitForActionProcess(action1);&nbsp; &nbsp; }&nbsp; &nbsp; public static void WaitForActionProcess(List<Action> action)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; action.Add(Both);&nbsp; &nbsp; &nbsp; &nbsp; // assignment passes a reference to the List&nbsp; &nbsp; &nbsp; &nbsp; actionHandler = action;&nbsp; &nbsp; &nbsp; &nbsp; action.Add(OnlyAction1);&nbsp; &nbsp; &nbsp; &nbsp; actionHandler.Add(OnlyActionHandler);&nbsp; &nbsp; &nbsp; &nbsp; // now things work nicely&nbsp; &nbsp; &nbsp; &nbsp; foreach(var a in action) a();&nbsp; &nbsp; &nbsp; &nbsp; foreach(var a in actionHandler) a();&nbsp; &nbsp; }&nbsp; &nbsp; public static void Both()=> Console.WriteLine("Both");&nbsp; &nbsp; public static void OnlyAction1() => Console.WriteLine("OnlyAction1");&nbsp; &nbsp; public static void OnlyActionHandler() => Console.WriteLine("OnlyActionHandler");}
打开App,查看更多内容
随时随地看视频慕课网APP