[C#] Geen return vanuit recursive functie

Pagina: 1
Acties:

Vraag


  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 02-10 16:09
Ik zit al 2 uur te ploeteren op een (ogenschijnlijk) simpel stukje code, maar ik krijg het niet voor elkaar.

Ik heb een table gemaakt in C#. De cellen hebben allemaal een unieke ID. Ik wil graag het cellcontrol opvragen aan de hand van de ID. Ik weet vooraf niet hoeveel rijen ik heb en hoeveel cellen er in die rijen zitten, dus ik heb een recursive function gemaakt als volgt:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public Control findControl(Control parent, string searchID)
{
  if (parent.ID == searchID) return parent;

  Control newControl = null;
  
  foreach(Control c in parent.Controls)
  {
    if (c.ID == searchID)
    {
      //newControl = c;
      //return newcontrol;
      return c;
    }
    else
    {
      findControl(c, searchID);
    }
  }
  return newControl;
}

Ik roep de code aanvouding aan middels:
C#:
1
var tempControl = findControl(layoutTable, "cell-9");

Echter, ondanks dat ik zie dat hij een control vindt (en stopt), returnt hij elke keer null...

Zoals je in de code ziet, heb ik ook al geprobeerd een variable te vullen en deze dan te returnen. Helaas, hetzelfde probleem.

Volgens mij zie ik iets heel basics over het hoofd of ik denk gewoon volledig verkeerd.

Iemand enig idee?

Beste antwoord (via Massiefje op 21-11-2019 19:58)


  • Daos
  • Registratie: Oktober 2004
  • Niet online
"even toewijzen aan newControl" is fout. Als de eerste iteratie van je foreach-loop het control vindt, dan overschrijft de volgende iteratie dat met null waardoor het resultaat dus null wordt. Returnen is het makkelijkst. Anders moet je gaan kloten met if-jes en extra variabelen.

Je kan je code dan nog opschonen naar:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public Control findControl(Control current, string searchID)
{
    if (current.ID == searchID) return current;

    foreach (Control child in current.Controls)
    {
        Control control = findControl(child, searchID);

        if (control != null)
        {
            return control;
        }
    }

    return null;
}

Alle reacties


  • EnnaN
  • Registratie: September 2002
  • Laatst online: 01-10 16:14

EnnaN

Toys in the attic

In regel 17 roep je findControl aan, maar je doet niets met het resultaat. Daar zul je iets mee moeten doen in combinatie met de newControl die je uiteindelijkl gaat returnen.

sig


  • Sleepkever
  • Registratie: Juni 2007
  • Laatst online: 04-10 20:59
Regel 17, je moet iets met de waarde doen die uit je recursief aangeroepen functie komt ;)
Even toewijzen aan newControl of ook returnen op dat punt (scheelt weer verder gaan in de array als het al gevonden is)

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 02-10 16:09
Heren, beide bedankt!

Sleepkever gaf het duidelijkste antwoord ("even toewijzen aan newControl) en dat bleek de oplossing te zijn.

Inderdaad dus iets over het hoofd gezien, zo logisch, maar zo snel gemist.

Mijn dank is groot!

Acties:
  • Beste antwoord
  • +4 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
"even toewijzen aan newControl" is fout. Als de eerste iteratie van je foreach-loop het control vindt, dan overschrijft de volgende iteratie dat met null waardoor het resultaat dus null wordt. Returnen is het makkelijkst. Anders moet je gaan kloten met if-jes en extra variabelen.

Je kan je code dan nog opschonen naar:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public Control findControl(Control current, string searchID)
{
    if (current.ID == searchID) return current;

    foreach (Control child in current.Controls)
    {
        Control control = findControl(child, searchID);

        if (control != null)
        {
            return control;
        }
    }

    return null;
}

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 02-10 16:09
Nadat ik de code had aangepast, leek het te werken, maar ineens stopte het ook weer :S Geen idee waarom.

Echter, nadat ik de code van DAOS pakte, lijkt het nu als een zonnetje te werken. Hopelijk blijft dat ook zo!

Thanks!

Acties:
  • 0 Henk 'm!

  • leverage010
  • Registratie: Oktober 2012
  • Laatst online: 10-04-2023
Massiefje schreef op donderdag 21 november 2019 @ 19:58:
Nadat ik de code had aangepast, leek het te werken, maar ineens stopte het ook weer :S Geen idee waarom.

Echter, nadat ik de code van DAOS pakte, lijkt het nu als een zonnetje te werken. Hopelijk blijft dat ook zo!

Thanks!
Maar begrijp je waarom het (niet) werkt? gebruik je de debugger om stap voor stap door de code te gaan?

edit: realiseer me nu pas de lichte necro :o

[ Voor 5% gewijzigd door leverage010 op 04-12-2019 18:57 ]


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 02-10 16:09
leverage010 schreef op woensdag 4 december 2019 @ 18:56:
[...]


Maar begrijp je waarom het (niet) werkt? gebruik je de debugger om stap voor stap door de code te gaan?

edit: realiseer me nu pas de lichte necro :o
Ja, ik begrijp hem nu ja! En het debuggen werkt (nog) niet helemaal lekker hier met een remote IIS en een lokale visual studio. En nog niet veel nodig gehad, behalve bij dit stukje code.

Ik weet dat het kan werken, heb er alleen nog geen aandacht aan besteed. Maar thanks voor het wijzen erop!

Acties:
  • +1 Henk 'm!

  • Corniel
  • Registratie: April 2002
  • Laatst online: 31-03 14:56

Corniel

De wereld is gek!

Massiefje schreef op donderdag 5 december 2019 @ 11:55:

Ja, ik begrijp hem nu ja! En het debuggen werkt (nog) niet helemaal lekker hier met een remote IIS en een lokale visual studio. (..)
Schrijf een unit test, dat is ook nog eens veel makkelijker te debuggen als dat nodig is:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Test]
public void FindControl_NonExistingId_Null()
{
    var control = new Control();
    var actual = Helper.FindControl(control, "someId");
    Assert.IsNull(actual);
}

[Test]
public void FindControl_ExistingId_Found()
{
    var control = new Control();
    var actual = Helper.FindControl(control, "someId");
    Assert.IsNotNull(actual);
    Assert.AreEqual("someId", actual.ID);
}

while (me.Alive) {
me.KickAss();
}


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Corniel schreef op zaterdag 4 januari 2020 @ 19:29:
[...]


Schrijf een unit test, dat is ook nog eens veel makkelijker te debuggen als dat nodig is
Dit stinkt naar ASP.NET WebForms en dat is alles behalve unit-testable.


Deze code is grotendeels ook niet nodig. Wil je een ID, een aan de huidige scope behorend server-control ID, terug vinden dan doe je dat middels de FindControl method, welke al recursief in de gehele naming container kijkt.

Als dat je scenario niet afdekt, dan ben je iets vreselijk fout aan het doen. Dikke kans dat je dan ID property hetzij als UniqueID hetzij als ClientID aan het interpreteren bent. En dat zijn echt verschillende zaken.

[ Voor 62% gewijzigd door R4gnax op 06-01-2020 20:46 ]

Pagina: 1