Avatar billede baileys Nybegynder
09. maj 2005 - 13:24 Der er 23 kommentarer

Brug af klasse, i klasse, i klasse, i klasse

Jeg har en masse funktioner, der er delt op i klasser, således at f.eks.

SystemFunctions
- getHeartBeat();
- getUptime();
- ....

PriceFunctions
- getRawPrice();
- getCalulatedPrice();
- ....

Problemet er, at hvis f.eks. disse to klasser bruger hinanden, ryger jeg ind i et "create-loop", hvor den ene klasse opretter den anden, som så opretter den ene (for at få adgang til dens funktioner m.m.) og så forfra igen.

Er der en smart måde jeg kan snige mig uden om dette uden at rette alt for meget i strukturen, eller er det bare en designmæssig bommert?
Avatar billede burningice Nybegynder
09. maj 2005 - 13:31 #1
Lader til at du bare skal lave alle dine funktioner static, og kalde dem direkte på klassen istedet for at oprette en instans først.
Avatar billede baileys Nybegynder
09. maj 2005 - 13:31 #2
En løsning kunne være at lave visse funktioner statiske, men da jeg bruger nogle andre oprettede objekter "globalt" i hele klassen, ville det nok heller ikke virke...
Avatar billede baileys Nybegynder
09. maj 2005 - 13:31 #3
F.eks. bruger jeg en database-forbindelse, som oprettes ved oprettelse af de enkelte klasser, til brug i hele klassen
Avatar billede nielle Nybegynder
09. maj 2005 - 13:33 #4
Hvis de to klasser bruger hinanden skal de vel pege på hinanden i stedet for blot at oprette en ny instans.
Avatar billede nielle Nybegynder
09. maj 2005 - 13:37 #5
Noget i stil med:

namespace Eksperten
{
    public class App
    {
        public static void Main(string[] args)
        {
            Class1 MC1 = new Class1();
        }
    }

    public class Class1
    {
        private Class2 C2;

        public Class1()
        {
            C2 = new Class2(this);
        }

        public Class1(Class2 class2)
        {
            C2 = class2;
        }
    }

    public class Class2
    {
        private Class1 C1;

        public Class2()
        {
            C1 = new Class1();
        }

        public Class2(Class1 class1)
        {
            C1 = class1;
        }
    }
}
Avatar billede nielle Nybegynder
09. maj 2005 - 13:38 #6
Ups. Lille rettelse:

public Class2(Class1 class1)
{
    C1 = new Class1(this);
}
Avatar billede nielle Nybegynder
09. maj 2005 - 13:40 #7
Igen-igen... :^(

public class Class2
{
    private Class1 C1;

    public Class2()
    {
        C1 = new Class1(this);
    }

    public Class2(Class1 class1)
    {
        C1 = class1;
    }
}
Avatar billede baileys Nybegynder
09. maj 2005 - 13:46 #8
Ahh - smart :D
Avatar billede baileys Nybegynder
09. maj 2005 - 13:47 #9
tester lige
Avatar billede baileys Nybegynder
09. maj 2005 - 14:11 #10
Dem fejler stadig, selvom jeg har implementeret din metode, dog på en meget mindre brutal måde end før, hvor hele serveren crashede og webapplikationen lukkede - for good.

Men stadig: Exception of type System.StackOverflowException was thrown.
Kigger videre for at se hvad der kan være galt...
Avatar billede nielle Nybegynder
09. maj 2005 - 14:15 #11
Vi skal nok have noget mere konkret kode hvis vi skal hjælpe mere.
Avatar billede burningice Nybegynder
09. maj 2005 - 14:55 #12
hvad med at lave de to klasser som singleton?
Avatar billede baileys Nybegynder
09. maj 2005 - 15:15 #13
Den skal jeg lige have uddybet...
Avatar billede nielle Nybegynder
09. maj 2005 - 15:18 #14
Min yndlingsartikel om Singelton-pattern:

http://www.yoda.arachsys.com/csharp/singleton.html

(Og resten af hans artikler er også værd at læse!)
Avatar billede baileys Nybegynder
09. maj 2005 - 15:40 #15
Lyder lovende - men når desværre ikke at implementere det i dag, så må vente med at prøve det af til i morgen - men smider lige en konklusion i morgen :)
Avatar billede arne_v Ekspert
09. maj 2005 - 21:42 #16
spændende artikel

og jeg skal vist have rettet min Singleton artikel her på E - jeg vil ikke
tilføje den mulighed med nested class den er for speciel, men jeg påstår
at double locking virker i .NET
Avatar billede nielle Nybegynder
10. maj 2005 - 10:24 #17
Problemet med din StackOverflowException tyder på at du har en situation - groft simplificeret - hvor en metode M1 i klassen Class1, som kalder en metode M2 i klassen Class2, som så for sin del kalder M1 igen:

namespace PocEksperten
{
    class App
    {
        [STAThread]
        static void Main(string[] args)
        {
            Class1 MC1 = new Class1();
            MC1.M1();
        }
    }

    public class Class1
    {
        private Class2 C2;

        public Class1()
        {
            C2 = new Class2(this);
        }

        public Class1(Class2 class2)
        {
            C2 = class2;
        }

        public void M1()
        {
            C2.M2();
        }
    }

    public class Class2
    {
        private Class1 C1;

        public Class2()
        {
            C1 = new Class1(this);
        }

        public Class2(Class1 class1)
        {
            C1 = class1;
        }

        public void M2()
        {
            C1.M1();
        }
    }
}

Måske kan der være flere led i kæden, eller også er det lidt mere kompliceret end som da, men StackOverflowException plejer som regel at betyde at man har en uendelig kæde af metode-kald.

Hvis det er det som er din fejl, så hjælper det desværre intet at gøre klasserne til Singletons. Der er kun et at gøre og det er at finde kæden og sikre sig at den bliver brudt.
Avatar billede baileys Nybegynder
10. maj 2005 - 10:33 #18
Godmorgen :)

Nu har jeg leget lidt med det, og må sige det har virkelig givet store hastighed-forøgelser i mine webapplikationer, men jeg oplever nogle problemer når jeg rammer mit "klasse-loop".

Det der sker, er bare at anden gang loop'et bliver ramt, bliver instancen ikke hentet fra den andet singleton-klasse - der bliver bare returneret en null-værdi, hvilket så fejler herefter.

Jeg benytter 4. metode i ovenstående artikel, og råt udskåret ser det sådan ud:

--------------------------------------
public sealed class HouseFunctions
{
  ...
  private CalendarFunctions calendarFunctions;

  private static readonly HouseFunctions instance = new HouseFunctions();

  public static HouseFunctions Instance
  {
    get { return instance; }
  }

  public HouseFunctions()
  {
    ...
    calendarFunctions = CalendarFunctions.Instance;
    ...
  }

  static HouseFunctions()
  {
  }

  ....
}
--------------------------------------

public sealed class CalendarFunctions
{
  ...
  private Functions.HouseFunctions houseFunctions;
 
  private static readonly CalendarFunctions instance = new CalendarFunctions();

  public static CalendarFunctions Instance
  {
    get { return instance; }
  }

  public CalendarFunctions()
  {
    houseFunctions = HouseFunctions.Instance;
    ...
  }

  static CalendarFunctions()
  {
  }

  ...
}
--------------------------------------

Jeg har desuden været nød til at fjerne mine dispose-funktioner.
Avatar billede baileys Nybegynder
10. maj 2005 - 10:36 #19
Nielle: Jeg ved hvad kæden er - to klasser som constructor hinanden i en uendelighed. Men er der ingen programmerbar måde ud af det, uden at skulle omstrukturere hele skidtet?
Avatar billede nielle Nybegynder
10. maj 2005 - 12:17 #20
Dit eksempel 10/05-2005 10:33:45 fungerer nu ellers fint uden at styrte her hos mig.

Du siger at loopen skyldes at constructors kalder constructors; Og der tror jeg altså at du tager fejl:

Jeg har angivet én mulig metode til at undgå dette, 09/05-2005 13:37:07, og du har prøvet denne. Den hjalp da også på situationen - med det "men" at du efterfølgende fik en StackOverflowException i stedet.

Du har også prøvet en anden mulig metode, 10/05-2005 10:33:45, nemlig at bruge Singleton-patteren. Den fungerer også fint uden at gå i loop.

At du stadig får en StackOverflowException må altså skyldes at det er nogen af de *andre* metoder i dine to klasser som går i loop. Desværre kan jeg ikke sige noget mere konkret uden at se den rigtige kode.
Avatar billede nielle Nybegynder
13. maj 2005 - 20:02 #21
Er du kommer videre?
Avatar billede nielle Nybegynder
24. juni 2005 - 17:44 #22
Lukketid?
Avatar billede nielle Nybegynder
27. november 2007 - 22:40 #23
Lukketid?!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester