Archief - c# hoe enum aanspreken in andere klasse (inheritance)

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

wyvernshill

Legacy Member
ok ik ben bezig met inheritance en heb 3 klasses:

Klasse B & C erven van klasse A.

In klasse B heb ik een enumeratie gemaakt met een aantal waarden (string).

Ik probeer nu in klasse A de enumeratie op te vragen om deze te kunnen gebruiken in een functie. Hoe kan ik deze enumeratie nu aanspreken ?

Bedankt voor enige info.

Wyvernshill

Parnakra

Legacy Member
Onmogelijk, aangezien je niet zeker kan zijn dat een object van klasse A altijd een instantie zal zijn van klasse B.

/edit: niet per sé onmogelijk, aangezien het met wat bricoleerwerk waarschijnlijk te doen valt, maar eerder afschuwelijke programmeerstijl en design.

Albireo

Legacy Member
ziehier mijn bricoleerwerkje :p

Ik definieer een "lege" enum in de basisklasse en maak in klasse B de echte enum. Zodoende kan je vanuit A altijd met de enum werken zonder je zorgen hoeven te maken met welke subklasse van A je bezig bent.

'k Wilde het aanvankelijk met virtual en override doen, maar dat gaat dus niet met enums in C#.

Code:
    class Program {
        static void Main(string[] args) {
            A a = new A();
            A b = new B();
            A c = new C();
            a.End();
            c.End();
            b.End();
        }
    }
    class A {
        public enum ErrorCode {
            NotApplicable
        }

        public virtual void End() {
            Console.WriteLine(ErrorCode.NotApplicable.ToString());
        }
    }
    class B : A {
        private Random d20 = new Random();
        public new enum ErrorCode {
            Success,Failure, CriticalFailure
            
        }
        public override void End() {
            int code = d20.Next(21);
            string msg = "";
            if (code < 10) {
                msg = ErrorCode.Success.ToString();
            }
            else if (code < 19) {
                msg = ErrorCode.Failure.ToString();
            }
            else {
                msg = ErrorCode.CriticalFailure.ToString();
            }
            Console.WriteLine(msg);
        }
    }
    class C : A {
    }

MAXXUR

Legacy Member
Duidelijk iets mis met uw structuur. Als A die enum ook moet kennen, moet die enum ook in A zitten. Als C die enum niet mag kennen, moet die maar ni afleiden van A.

Albireo

Legacy Member
Wat de OP letterlijk vraagt wijst op een probleem in de structuur van het programma. Als je dat echter wat mooier verpakt wordt het design en noemt men het een template method.

Een iets eleganter voorbeeld:
Code:
    class Program {
        static void Main(string[] args) {
            A a = new A();
            A b = new B();
            A c = new C();
            a.End();
            b.End();
            c.End();
        }
    }
    class A {
        public virtual void End() {
        }
    }
    class B:A {
        private Random d20 = new Random();
        public enum ErrorCode {
            Success, Failure, CriticalFailure
        }
        public override void End() {
            int code = d20.Next(21);
            ErrorCode msg;
            if (code < 10) {
                msg = ErrorCode.Success;
            }
            else if (code < 19) {
                msg = ErrorCode.Failure;
            }
            else {
                msg = ErrorCode.CriticalFailure;
            }
            Console.WriteLine(msg.ToString());
        }
    }
    class C:A { 
    }

Albireo

Legacy Member
Parnakra zei:
Gedrag != toestand.

Kan je daar even over uitwijden?

Ik heb ervoor gezorgd dat klasse A een functie kan gebruiken die, indien klasse A B is, toegang heeft tot de enum. De techniek die ik daarvoor gebruikt hebt is volgens mij volkomen normaal OO design.

Albireo

Legacy Member
Ik volhard in de boosheid. :) Een andere manier om die enum te kunnen gebruiken in een functie in A zonder dat A hoeft te weten dat B bestaat.
Code:
class Program {
        static void Main(string[] args) {
            A a = new A();
            A b = new B();
            A c = new C();
            IErrorCodeProvider errorCodeProvider =new B();
            a.End(errorCodeProvider);
            c.End(errorCodeProvider);
            b.End(errorCodeProvider);
        }
    }
    interface IErrorCodeProvider {
        void ReturnMessage(int state);
    }
    class A {
        protected int state=0;
        public virtual void End(IErrorCodeProvider prov) {
            prov.ReturnMessage(state);
        }
    }
    class B : A,IErrorCodeProvider {
        private enum ErrorCode {
            Success,Failure, CriticalFailure
            
        }
        public void ReturnMessage(int code) {
            ErrorCode msg;
            if (code < 10) {
                msg = ErrorCode.Success;
            }
            else if (code < 19) {
                msg = ErrorCode.Failure;
            }
            else {
                msg = ErrorCode.CriticalFailure;
            }
            Console.WriteLine(msg.ToString());
        }
    }
    class C : A {
    }

Parnakra

Legacy Member
Albireo zei:
Kan je daar even over uitwijden?
Het template design pattern handelt over methodes, ergo over het gedrag van je klasse. Een enum-attribuut behoort tot de toestand van een klasse. Iets volkomen anders, m.a.w.

En dit druist volledig in tegen de OO principes. :s Als je die enum vanuit A wil kunnen gebruiken, houdt dat in dat die enum in A moet zitten. Point final. Elke klasse die dan erft van A zal ook over die enum beschikken, dus C ook.

Als dit niet is hoe je het wil (wat blijkbaar de OP zijn probleem is), schort er iets aan je ontwerp.

/edit: in je bovenstaand voorbeeld kan een object van klasse C nu trouwens ook aan die enum.

Albireo

Legacy Member
De vraag is, wat bedoelt de OP precies met "vanuit A kunnen gebruiken".

Als ik in m'n 2de voorbeeld schrijf
Code:
A b = new B();
b.End();
dan vind ik dat ik de enum gebruikt hebt vanuit A omdat b duidelijk van de klasse A is en het toch de code in B is, waar de enum (die desgewenst private kan zijn) zit, die uitgevoerd wordt. En omdat dat A op geen enkele manier afhankelijk maakt van B vind ik dat goed OO-design.

Die End() method een template method noemen gaat er een beetje over. 't Is daar een hook, maar ik heb over hooks geleerd toen het over template methods ging. Vandaar... :unsure:

MAXXUR

Legacy Member
de OP denkt nu holy shit what the fuck ik wil gewoon die enum in A gebruiken

Cycloon

Legacy Member
Albireo zei:
Ik volhard in de boosheid. :) Een andere manier om die enum te kunnen gebruiken in een functie in A zonder dat A hoeft te weten dat B bestaat.

Het gedrag van je klasse B zal dezelfde zijn als die van klasse A, enkel de toestand die je toont aan de buitenwereld is anders (afhankelijk van je enum). Op zich is daar niks mis mee naar mijn mening, maar de praktische waarde van dit soort constructies lijkt me vrij beperkt.

Parnakra

Legacy Member
Code:
    class A {
        public void Foo() {
            ...
            ErrorCode bla = ErrorCode.Success
            ...
        }
    }
    class B : A {
        private enum ErrorCode {
            Success,Failure, CriticalFailure
        }
    }
Volgens mij bedoelt OP eerder zoiets.

Albireo

Legacy Member
MAXXUR zei:
de OP denkt nu holy shit what the fuck ik wil gewoon die enum in A gebruiken

:rofl:

aan de OP: als je het op de "slechte" manier wil doen
Code:
class A {
  public function MyFunction {
    Console.WriteLine(B.MyEnum.MyValue.ToString());
  }
}
class B : A {
  public enum MyEnum {MyValue, MyOtherValue, MyLastValue}
}

PS. Je kan een enum ook rechtstreeks in je namespace definiëren. Het hoeft niet in een class te staan.
PPS. Kan je je code eens posten?

wyvernshill

Legacy Member
hmmm inderdaad , ik was al aan het denken van mijn enum te verplaatsen naar A, maar ik heb het meestal lastig om iets "logisch" te bekijken :)

Maakt het alleen maar moeilijker om programmeur te worden. Maar ik volhard in de boosheid !

Bedankt voor de info, dus ik zal eerst proberen mijn structuur te veranderen :)

Gurdt

Legacy Member
Zo dingen kan je best op papier uit tekenen, dat wordt in de praktijk ook uitvoerig gedaan. Als er in een bedrijf software gebouwd wordt, zullen ze eerst tot in de puntjes uitzoeken hoe iets gestructureerd zal zijn, nog lang voor er enige code getypt wordt.

Er zijn ook uitstekende boeken die hier over gaan, object georiënteerd programmeren. Daar zitten leuke denkoefeningen in enz :) Het is iets wat je aanleert door het vaak te doen dus zeker volharden! Je zal daar geen spijt van krijgen ;)

forloRn_

Legacy Member
Gurdt zei:
Als er in een bedrijf software gebouwd wordt, zullen ze eerst tot in de puntjes uitzoeken hoe iets gestructureerd zal zijn, nog lang voor er enige code getypt wordt.

En ik denk dat je je verwachtingen enigszins bij moet stellen.

Gurdt

Legacy Member
forloRn_ zei:
En ik denk dat je je verwachtingen enigszins bij moet stellen.

Please tell me more.

Ooit van software engineering gehoord? Bedrijven waar dit niet toegepast wordt leveren wellicht enkel crappy software. Ik zou alleszins geen rotte euro geven aan een team dat niet eerst uitzoekt hoe iets ineen moet steken alvorens ze het gaat bouwen voor mij :)
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan