将一个函数指向另一个函数

Pointing a function to another

假设我有两个函数:

void DoesNothing(){}

void OnlyCalledOnce(){
    //lines of code
}

是否可以调用 OnlyCalledOnce 而实际上是 运行 DoesNothing ?我想象这样的事情:

void DoesNothing(){}

void OnlyCalledOnce(){
    //lines of code
    OnlyCalledOnce = DoesNothing;
}

在最后一行之后,每当我调用 OnlyCalledOnce 时,它都会 运行 DoesNothing.

可能吗?

您可以在 OnlyCalledOnce 的早期简单地 return 像这样:(假设您的 DoesNothing 示例实际上什么都不做 - 它不需要)

bool initialized = false;

void OnlyCalledOnce()
{
    if (initialized) return;

    // firsttimecode
    initialized = true;
}

initialized 变量在第一个 运行 之后将是 true

如前所述,您可以使用这个:

private bool isExecuted = false;

void DoesNothing(){}

void OnlyCalledOnce(){
    if (!isExecuted)
    {   
        isExecuted = true;
        //lines of code
        DoesNothing();
    }
}

如果你有多个线程等,你可以做一个锁(对象)..

你有什么问题吗?

void DoesNothing()
{
}

void OnlyCalledOnce()
{
    DoesNothing();
}

它会 运行 DoesNothing() 一旦你 运行 OnlyCalledOnce()

您尝试过使用委托吗?

class Program
{
    private static Action Call = OnlyCalledOnce;

    public static void Main(string[] args)
    {
        Call();
        Call();
        Call();
        Console.ReadKey();
    }

    static void DoesNothing()
    {
        Console.WriteLine("DoesNothing");
    }

    static void OnlyCalledOnce()
    {
        Console.WriteLine("OnlyCalledOnce");
        Call = DoesNothing;
    }
}

解决此问题的另一种方法是维护一个表示已调用方法的字符串列表。字符串甚至不必是方法名称,它们只需要对每个方法都是唯一的。

然后你可以有一个名为 ShouldIRun 的辅助方法,它接受函数的唯一字符串并检查它是否存在于列表中。如果是,则方法 returns false,如果不是,则该方法将字符串添加到列表和 returns true.

这里的好处是您不必维护一堆状态变量,您可以根据需要将其与任意多的方法一起使用,并且方法本身不需要任何复杂的逻辑 - 它们只是询问助手是否应该 运行 或不应该!

public class Program
{
    private static List<string> CalledMethods = new List<string>();

    static bool ShouldIRun(string methodName)
    {
        if (CalledMethods.Contains(methodName)) return false;
        CalledMethods.Add(methodName);
        return true;
    }

    // Now this method can use method above to return early (do nothing) if it's already ran
    static void OnlyCalledOnce()
    {
        if (!ShouldIRun("OnlyCalledOnce")) return;

        Console.WriteLine("You should only see this once.");
    }

    // Let's test it out
    private static void Main()
    {
        OnlyCalledOnce();
        OnlyCalledOnce();
        OnlyCalledOnce();

        GetKeyFromUser("\nDone! Press any key to exit...");
    }
}

输出