Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: mikesznovu 06. 12. 2022, 23:38:37

Název: Neomezená rekurze při foreach C#
Přispěvatel: mikesznovu 06. 12. 2022, 23:38:37
Dojde zde k "neomezené rekurzi" ? Je tento (1,2) kod optimální? Samozřejmě strom je konečný, ale  volá se yieldnode/applynode. Nejde mi o rekurzi stromu a pricipu algoritmu (což jsou) ale o kód, jestli roste stack frame s hloubkou stromu

Případně pokud ano , dokáže se s tim kompilator poprat ((tail)optimalizace, dekompozice na "goto")?

Kód: [Vybrat]
1

public IEnumerator<T> GetEnumerator()
{
    foreach (var item in YieldNode(_root))
        yield return item;
}

private IEnumerable<T> YieldNode(Node<T> node)
{
    if (node == null)
        yield break;

    foreach (var item in YieldNode(node.Left))
        yield return item;

    yield return node.Item;

    foreach (var item in YieldNode(node.Right))
        yield return item;
}

2:

public void ForEach(Action<T> action)
{
    ApplyToNode(_root, action);
}

private void ApplyToNode(Node<T> node, Action<T> action)
{
    if (node == null)
        return;

    ApplyToNode(node.Left, action);
    action(node.Item);
   
Název: Re:stanese neomezená rekurze při foreach c#
Přispěvatel: ludva.eth 07. 12. 2022, 01:02:43
Myslíš zda dojde k přetečení zásobníku (StackOverflowException)? Volání metody samozřejmě zvětšuje zásobník, takže ano. Ten je ale dost velký, takže pokud nemáš hodné hluboký strom, tak by to nemělo vadit.
Yield return je vlastně obyčejný stavový automat a metoda se přepíše na třídu. Volání takové metody tedy na haldě vytvoří nový objekt na kterém vždy volá metodu stavového automatu pro získání dalšího prvku.
Název: Re:Neomezená rekurze při foreach C#
Přispěvatel: oss 07. 12. 2022, 08:05:25
> Dojde zde k "neomezené rekurzi" ?

Nie.

> Je tento (1,2) kod optimální?

Ano.