Указание функции на другую - PullRequest
       9

Указание функции на другую

0 голосов
/ 03 сентября 2018

Предположим, у меня есть две функции:

void DoesNothing(){}

void OnlyCalledOnce(){
    //lines of code
}

Можно ли позвонить OnlyCalledOnce и он на самом деле работает DoesNothing? Я представляю что-то вроде этого:

void DoesNothing(){}

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

и после этой последней строки всякий раз, когда я звонил OnlyCalledOnce, он запускал DoesNothing.

Возможно ли это?

Ответы [ 5 ]

0 голосов
/ 20 сентября 2018

Другим способом решения этой проблемы является ведение списка строк, которые представляют методы, которые были вызваны. Строки даже не должны быть именем метода, они просто должны быть уникальными для каждого метода.

Тогда у вас может быть вспомогательный метод с именем ShouldIRun, который принимает уникальную строку функции и проверяет, существует ли она в списке. Если это так, то метод возвращает false, а если нет, то метод добавляет строку в список и возвращает 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...");
    }
}

Выход

enter image description here

0 голосов
/ 03 сентября 2018

Вы пытались использовать делегат?

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;
    }
}
0 голосов
/ 03 сентября 2018

Как уже говорилось, вы можете использовать это:

private bool isExecuted = false;

void DoesNothing(){}

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

Если у вас несколько потоков и т. Д., Вы можете сделать блокировку (объект) ..

0 голосов
/ 03 сентября 2018

В чем ваша проблема с этим?

void DoesNothing()
{
}

void OnlyCalledOnce()
{
    DoesNothing();
}

При запуске OnlyCalledOnce () * он запустит DoesNothing ()

0 голосов
/ 03 сентября 2018

Вы можете просто вернуться рано в OnlyCalledOnce следующим образом: (если ваш DoesNothing пример буквально ничего не делает - он не нужен)

bool initialized = false;

void OnlyCalledOnce()
{
    if (initialized) return;

    // firsttimecode
    initialized = true;
}

Переменная initialized будет true после первого запуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...