Neomezená rekurze při foreach C#

Neomezená rekurze při foreach C#
« kdy: 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);
   
« Poslední změna: 07. 12. 2022, 08:01:40 od Petr Krčmář »


Re:stanese neomezená rekurze při foreach c#
« Odpověď #1 kdy: 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.

oss

  • ***
  • 229
    • Zobrazit profil
    • E-mail
Re:Neomezená rekurze při foreach C#
« Odpověď #2 kdy: 07. 12. 2022, 08:05:25 »
> Dojde zde k "neomezené rekurzi" ?

Nie.

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

Ano.