Toon posts:

[C#] Eigenschappen aanroepen met zelfde inheritance

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als ik een aantal classes heb die van een zelfde (abstacte) class erven, hoe kan ik dan het beste de properties benaderen, maar zodat deze wel op het het geerfde object worden toegepast, maar zonder dat ik de exacte implementatie van het eigenlijke object weet?

Stel, je hebt een abstracte class Shapes... en je hebt een aantal classes zoals Rectangle, Triangle en Ellipse, dan wil ik kunnen testen of iets een shape is, en bijvoorbeeld de Fill kleur van deze objecten kunnen aanpassen. Hoe zet ik dit technisch goed op? Zodat als ik een nieuwe shape kan toevoeg, toch met een tool oid de kleur kunnen laten aanpassen zonder dat deze tool opnieuw gecompileerd hoeft te worden, of weet welke classes er exact zijn?

Oplossing mag uiteraard, maar een schop in de juiste richting is ook prima, dank!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 12:48

gorgi_19

Kruimeltjes zijn weer op :9

methods abstract (MustOverride / Overridable in VB.Net) definieren in een baseclass en deze vervolgens overriden in de specifieke implementatie?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Shape
{
  public abstract bool IsRectangle { get; }
}

public class Rectangle : Shape
{
  public override bool IsRectangle
 {
   get { return true; /*doe hier iets nuttigers*/ }
}
}



Dit had je overigens ook zelf kunnen verzinnen, want alle C# IDE's geven zelf al aan dat je moet overriden als je een fout maakt...

Verwijderd

Topicstarter
He, gadver inderdaad. Ik had al verwacht dat het zo simpel moest zijn, maar omdat ik een hint van de compiler kreeg dat als ik een property wilde herdefinieren, ik "new" moest gebruiken, en dat werkte verder prima, maar toen riep hij de functie van Shape aan ipv bv Rectangle, die ik vergeten was abstract te maken... Sorry! Was de weg gewoon even kwijt denk ik |:(

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je hoeft ze niet perse abstract te maken. Als je al een goede definitie ergens van hebt maar mischien in een sub-class wil overerven kan je hem ook virtual maken. In het geval van een Color is dat natuurlijk logischer ( Als je er uberhaupt al een andere implementatie voor hebt ). Dan doe je het bv zo
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Shape
{
    public abstract void Draw(Graphics g);

    private Color foreColor;

    public virtual Color ForeColor
    {
        get { return foreColor; }
        set { foreColor = value; }
    }
}

Draw moet je hier perse implementeren en voor foreColor kan je een nieuwe implementatie geven als je dat nodig vind ( override keyword )

[ Voor 4% gewijzigd door Woy op 26-02-2007 21:29 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op maandag 26 februari 2007 @ 20:28:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Shape
{
  public abstract bool IsRectangle { get; }
}

public class Rectangle : Shape
{
  public override bool IsRectangle
 {
   get { return true; /*doe hier iets nuttigers*/ }
}
}



Dit had je overigens ook zelf kunnen verzinnen, want alle C# IDE's geven zelf al aan dat je moet overriden als je een fout maakt...
Dat lijkt me niet de bedoeling te kunnen zijn. Je zou met zo'n `oplossing' dus voor elke subtype van Shape een flag moeten maken, wat best onzinnig is, aangezien je dan net zo goed met "is" kan werken, i.e. "someInstance is Rectangle". Maar op het moment dat je moet vragen van een object wat voor type het is moet je jezelf eens gaan afvragen of je wel juist bezig bent, want 9/10 keer kun je met polymorfie bewerkstelligen wat je wil.
Volgens mij zoekt TS, tenminste, voor zoverre ik kan opmaken uit de fuzzy beschrijving, het volgende:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Shape
{
  public abstract void fill(Color c);
}

public class Rectangle : Shape
{
    public override void fill(Color c)
    {
        //assign color to this shape
    }
}


Vervolgens werk je dan gewoon met:
C#:
1
2
Shape s = new Rectangle(); // de provider van Shape is nu een instance van Rectangle. s kan je natuurlijk zo assignen voor elke subtype van Shape.
s.fill(c); //fill wordt invoked op de provider van Shape, i.e. Rectangle.

Verwijderd

Verwijderd schreef op maandag 26 februari 2007 @ 20:28:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class Shape
{
  public abstract bool IsRectangle { get; }
}

public class Rectangle : Shape
{
  public override bool IsRectangle
 {
   get { return true; /*doe hier iets nuttigers*/ }
}
}



Dit had je overigens ook zelf kunnen verzinnen, want alle C# IDE's geven zelf al aan dat je moet overriden als je een fout maakt...
Ik ga ervan uit dat je toch niet deze code gebruikt om te achterhalen of iets van een bepaald sub-type is? Dit druist namelijk tegen alle OO regels in omdat nu de super-class van het bestaan moet weten van zijn sub-classes.

Dit zou nettere code zijn:

code:
1
2
3
4
5
6
Rectangle r = new Rectangle();

        if (r.GetType() == typeof(Rectangle))
        {
            System.Diagnostics.Debug.WriteLine("It's a rectangle!");
        }


@topic starter:
Als je dynamisch at runtime classes uit andere assemblies wil inladen moet je het maar laten weten, dan mail ik wel een abstract factory method die dat kan.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op maandag 26 februari 2007 @ 21:32:
[...]

Dit zou nettere code zijn:

code:
1
2
3
4
5
6
Rectangle r = new Rectangle();

        if (r.GetType() == typeof(Rectangle))
        {
            System.Diagnostics.Debug.WriteLine("It's a rectangle!");
        }
Dit zou nog nettere code zijn

C#:
1
2
3
4
5
Shape s = new Rectangle();
if( s is Rectangle )
{
    ....
}

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Spuit 11 voor rwb en tassadar71 :P ;) O-)

[ Voor 6% gewijzigd door prototype op 26-02-2007 21:38 ]


Verwijderd

prototype schreef op maandag 26 februari 2007 @ 21:31:
[...]


Dat lijkt me niet de bedoeling te kunnen zijn. Je zou met zo'n `oplossing' dus voor elke subtype van Shape een flag moeten maken, wat best onzinnig is, aangezien je dan net zo goed met "is" kan werken, i.e. "someInstance is Rectangle". Maar op het moment dat je moet vragen van een object wat voor type het is moet je jezelf eens gaan afvragen of je wel juist bezig bent, want 9/10 keer kun je met polymorfie bewerkstelligen wat je wil.
:> Het is ook maar een voorbeeld om het duidelijk te maken. Als ik het abstracter had gedaan was het minder snel duidelijk geweest.... Je kunt beter iets op een trivale manier uitleggen, dat blijkt vaak toch het beste te werken voor de mensen...

De Draw methode was trouwens inderdaad een betere uitleg geweest qua OO, maar daar kwam ik dus ff niet op :P
Vervolgens werk je dan gewoon met:
C#:
1
2
Shape s = new Rectangle(); // de provider van Shape is nu een instance van Rectangle. s kan je natuurlijk zo assignen voor elke subtype van Shape.
s.fill(c); //fill wordt invoked op de provider van Shape, i.e. Rectangle.
Dit is overigens ook niet echt de bedoeling als je toch alweet dat je een Rectangle gaat maken...

[ Voor 23% gewijzigd door Verwijderd op 26-02-2007 21:41 ]


  • rainmaker2k
  • Registratie: Juli 2002
  • Laatst online: 26-10 14:19
rwb schreef op maandag 26 februari 2007 @ 21:37:
[...]

Dit zou nog nettere code zijn

C#:
1
2
3
4
5
Shape s = new Rectangle();
if( s is Rectangle )
{
    ....
}
Dit is volgens mij ook de meest nette manier om het op te lossen.

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op maandag 26 februari 2007 @ 21:38:
[...]


:> Het is ook maar een voorbeeld om het duidelijk te maken. Als ik het abstracter had gedaan was het minder snel duidelijk geweest.... Je kunt beter iets op een trivale manier uitleggen, dat blijkt vaak toch het beste te werken voor de mensen...

De Draw methode was trouwens inderdaad een betere uitleg geweest qua OO, maar daar kwam ik dus ff niet op :P
Dat is idd de manier ja, je publiek onderschatten en voeden met incorrecte antwoorden :P
[...]


Dit is overigens ook niet echt de bedoeling als je toch alweet dat je een Rectangle gaat maken...
Jij mag denk ik eens opnieuw OO doen :+, EN begrijpend lezen ;) In de opmerking staat dat hier gewerkt wordt met een declarative type die abstracter is dan Rectangle. Hierdoor is het mogelijk om elke subtype van de declarative type te assignen aan s, omdat deze altijd 'naar boven gecast' kunnen worden.
rainmaker2k schreef op maandag 26 februari 2007 @ 21:43:
[...]


Dit is volgens mij ook de meest nette manier om het op te lossen.
Nee, dat is het niet. ;)

[ Voor 10% gewijzigd door prototype op 26-02-2007 21:52 ]


Verwijderd

prototype schreef op maandag 26 februari 2007 @ 21:49:
[...]

Dat is idd de manier ja, je publiek onderschatten en voeden met incorrecte antwoorden :P


[...]


Jij mag denk ik eens opnieuw OO doen :+, EN begrijpend lezen ;) In de opmerking staat dat hier gewerkt wordt met een declarative type die abstracter is dan Rectangle. Hierdoor is het mogelijk om elke subtype van de declarative type te assignen aan s, omdat deze altijd 'naar boven gecast' kunnen worden.
En dat is gewenst bij direct casting omdat? Absoluut niet gewenst zelfs, OO overdone is dat... Zoiets dien je te gebruiken wanneer je meerdere subtypes kan verwachten van het zelfde basis type, bijvoorbeeld bij het tekenen van een plaatje met daarin objecten (Om maar bij de rectangles en circles te blijven), maar niet in deze vorm.

  • rainmaker2k
  • Registratie: Juli 2002
  • Laatst online: 26-10 14:19
Tuurlijk wel.. Als je bepaalde functies wil aanroepen die alleen Rectangle heeft, dan is dit de meest geschikte manier.

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

rainmaker2k schreef op maandag 26 februari 2007 @ 21:57:
[...]


Tuurlijk wel.. Als je bepaalde functies wil aanroepen die alleen Rectangle heeft, dan is dit de meest geschikte manier.
Maar juist daar gaat het niet om in deze topic...
Verwijderd schreef op maandag 26 februari 2007 @ 21:53:
[...]


En dat is gewenst bij direct casting omdat? Absoluut niet gewenst zelfs, OO overdone is dat... Zoiets dien je te gebruiken wanneer je meerdere subtypes kan verwachten van het zelfde basis type, bijvoorbeeld bij het tekenen van een plaatje met daarin objecten (Om maar bij de rectangles en circles te blijven), maar niet in deze vorm.
Direct casting? Volgens mij praten we langs elkaar heen... De oplossing die ik heb aangedragen is geschikt voor als je wil werken met Shapes in het algemeen en niet je druk wil maken over wat het nou PRECIES is, hetgeen wat TS wil voor zover ik op kan maken. Dit is perfect in lijn met het concept van "Abstractie" binnen OO.
Wat jij zou aanraden, i.e. een declarative type gebruiken die exact de provider type is, is te concreet. Vergelijk het met ArrayList<Foo> gebruiken als declarative type ipv List<Foo>. Als jij ooit de provider van die list wil veranderen heb jij een leuk refactor probleem aan je handen.

[ Voor 64% gewijzigd door prototype op 26-02-2007 22:05 ]


Verwijderd

rainmaker2k schreef op maandag 26 februari 2007 @ 21:57:
[...]


Tuurlijk wel.. Als je bepaalde functies wil aanroepen die alleen Rectangle heeft, dan is dit de meest geschikte manier.
Nee, dan doe je gewoon:
C#:
1
Rectangle rect = new Rectangle();


en niet:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Shape shape = new Rectangle();
if(shape is Rectangle) 
{
  ((Rectangle)shape).Scale(2);

}

of (wat netter):


Rectangle rect = shape as Rectangle;
if(rect != null)
{  
 rect.Scale(2);
}

[ Voor 3% gewijzigd door Verwijderd op 26-02-2007 22:03 ]


Verwijderd

prototype schreef op maandag 26 februari 2007 @ 21:59:
[...]

Maar juist daar gaat het niet om in deze topic...


[...]

Direct casting? Volgens mij praten we langs elkaar heen... De oplossing die ik heb aangedragen is geschikt voor als je wil werken met Shapes in het algemeen en niet je druk wil maken over wat het nou PRECIES is, hetgeen wat TS wil voor zover ik op kan maken. Dit is perfect in lijn met het concept van "Abstractie" binnen OO.
Wat jij zou aanraden, i.e. een declarative type gebruiken die exact de provider type is, is te concreet. Vergelijk het met ArrayList<Foo> gebruiken als declarative type ipv List<Foo>. Als jij ooit de provider van die list wil veranderen heb jij een leuk refactor probleem aan je handen.
Ik zie nu pas dat ik de verkeerde gequote heb eigenlijk, dus we gingen inderdaad langs elkaar af. :+. Alhoewel ctrl+shift+R gewoon goed refactored hoor O-)

[ Voor 5% gewijzigd door Verwijderd op 26-02-2007 22:10 ]


  • rainmaker2k
  • Registratie: Juli 2002
  • Laatst online: 26-10 14:19
Verwijderd schreef op maandag 26 februari 2007 @ 22:00:
[...]


Nee, dan doe je gewoon:
C#:
1
Rectangle rect = new Rectangle();
Vind je dit flexibel? Stel dat je op een gegeven moment niet meer een Rectangle nodig hebt, maar een Circle. Dan moet je hier alleen al 2 keer iets in de code veranderen.
Als je hem als Shape declareert, dan hoeft het nog maar een keer.

Wat ik hiermee wil zeggen is dat code geschreven moet zijn om makkelijk te kunnen worden geupdate.

Verwijderd

rainmaker2k schreef op maandag 26 februari 2007 @ 22:09:
[...]


Vind je dit flexibel? Stel dat je op een gegeven moment niet meer een Rectangle nodig hebt, maar een Circle. Dan moet je hier alleen al 2 keer iets in de code veranderen.
Als je hem als Shape declareert, dan hoeft het nog maar een keer.

Wat ik hiermee wil zeggen is dat code geschreven moet zijn om makkelijk te kunnen worden geupdate.
Eh, lees eens goed? En je code flexibel maken is overdone wanneer het niet nodig is. Code dient niet geschreven te zijn om makkelijk updatebaar te zijn. Het moet onderhoudbaar en zo goedkoop mogelijk gebouwd worden. Wanneer de klant een vierkant als front end verwacht, ga je niet voor een miljoen aan de applicatie verbouwen omdat jij vind dat het ook een cirkel kan worden.... Daar gaat je klant niet eens voor betalen.

[ Voor 29% gewijzigd door Verwijderd op 26-02-2007 22:12 ]


  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 14:37

RayNbow

Kirika <3

Verwijderd schreef op maandag 26 februari 2007 @ 21:53:
[...]


En dat is gewenst bij direct casting omdat? Absoluut niet gewenst zelfs, OO overdone is dat... Zoiets dien je te gebruiken wanneer je meerdere subtypes kan verwachten van het zelfde basis type, bijvoorbeeld bij het tekenen van een plaatje met daarin objecten (Om maar bij de rectangles en circles te blijven), maar niet in deze vorm.
Daar waar je met een generieker type kan werken, behoor je je variabelen ook zo generiek mogelijk te declareren. Dit bevordert de onderhoudbaarheid van je code.
en niet:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Shape shape = new Rectangle();
if(shape is Rectangle) 
{
  ((Rectangle)shape).Scale(2);

}

of (wat netter):


Rectangle rect = shape as Rectangle;
if(rect != null)
{  
 rect.Scale(2);
}
Code met is of instanceOf achtige constructies zijn vaak (niet altijd) een bad smell. Kijk dan liever of je de check kunt verwijderen door een method call waarbij er gedispatcht wordt op de argument types.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op maandag 26 februari 2007 @ 22:00:
[...]


Nee, dan doe je gewoon:
C#:
1
Rectangle rect = new Rectangle();


en niet:

C#:
1
2
3
4
5
6
Shape shape = new Rectangle();
if(shape is Rectangle) 
{
  ((Rectangle)shape).Scale(2);

}
Dit is downcasten, en als je dacht ik dat bedoelde heb je me verkeerd begrepen. Ik denk dat ik mijn punt het best duidelijk kan maken met het volgende voorbeeld en dan in java, aangezien generics daar wat prettiger mee te noteren zijn ;)

Java:
1
2
3
4
5
6
List<? extends Shape> shapes = new ArrayList<? extends Shape>();
shapes.add(new Rectangle());
shapes.add(new Circle());
for (Shape s : shapes) {
   s.fill(c);
}

Verwijderd

RayNbow schreef op maandag 26 februari 2007 @ 22:10:
[...]

Daar waar je met een generieker type kan werken, behoor je je variabelen ook zo generiek mogelijk te declareren. Dit bevordert de onderhoudbaarheid van je code.


[...]

Code met is of instanceOf achtige constructies zijn vaak (niet altijd) een bad smell. Kijk dan liever of je de check kunt verwijderen door een method call waarbij er gedispatcht wordt op de argument types.
Jij ook ff lezen en vooral ff MSDN coding guidelines erbij pakken. Die raadt namelijk "is" en "as" aan. Bekijk ze ook maar eens op IL niveau, dan zie je een geoptimaliseerde versie van wat jij normaal zelf doet.

Verwijderd

prototype schreef op maandag 26 februari 2007 @ 22:13:
[...]


Dit is downcasten, en als je dacht ik dat bedoelde heb je me verkeerd begrepen. Ik denk dat ik mijn punt het best duidelijk kan maken met het volgende voorbeeld en dan in java, aangezien generics daar wat prettiger mee te noteren zijn ;)

Java:
1
2
3
4
5
6
List<? extends Shape> shapes = new ArrayList<? extends Shape>();
shapes.add(new Rectangle());
shapes.add(new Circle());
for (Shape s : shapes) {
   s.fill(c);
}
Klopt, enige waar ik op doel is dat je niet nodeloos Shape moet gaan gebruiken als je toch al weet dat het altijd een Rectangle is. In jouw voorbeeld hier weet je dat dus inderdaad niet en dien je Shape te gebruiken.

Wat is java generics trouwens onoverzichtelijk op deze manier. Kan je niet gewoon List<Shape> doen?

[ Voor 6% gewijzigd door Verwijderd op 26-02-2007 22:19 ]


  • rainmaker2k
  • Registratie: Juli 2002
  • Laatst online: 26-10 14:19
Verwijderd schreef op maandag 26 februari 2007 @ 22:10:
[...]


Eh, lees eens goed? En je code flexibel maken is overdone wanneer het niet nodig is. Code dient niet geschreven te zijn om makkelijk updatebaar te zijn. Het moet onderhoudbaar en zo goedkoop mogelijk gebouwd worden. Wanneer de klant een vierkant als front end verwacht, ga je niet voor een miljoen aan de applicatie verbouwen omdat jij vind dat het ook een cirkel kan worden.... Daar gaat je klant niet eens voor betalen.
Als jij je code goed geschreven hebt, dan heb je niet eens Rectangle specifieke methodes nodig en volstaat het misschien zelfs om een interface te gebruiken ipv het uitbreiden van een klasse.

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op maandag 26 februari 2007 @ 22:15:
[...]


Klopt, enige waar ik op doel is dat je niet nodeloos Shape moet gaan gebruiken als je toch al weet dat het altijd een Rectangle is. In jouw voorbeeld hier weet je dat dus inderdaad niet en dien je Shape te gebruiken.
Maar dat is dus voor zover ik kan opmaken uit TS's verhaal niet relevant, en meer dan triviaal...
Wat is java generics trouwens onoverzichtelijk op deze manier. Kan je niet gewoon List<Shape> doen?
Nee, lees je maar eens in mbt covariance bij generics ;) C# heeft geen wildcard , zou je moeten simuleren wat meer code zou vereisen. Daarom deed ik het even in java en 'k sta daar ook wat sterker in. Ik weet namelijk niet of het wel opgaat in C#.

[ Voor 10% gewijzigd door prototype op 26-02-2007 22:28 ]


  • rainmaker2k
  • Registratie: Juli 2002
  • Laatst online: 26-10 14:19
RayNbow schreef op maandag 26 februari 2007 @ 22:10:
[...]

Daar waar je met een generieker type kan werken, behoor je je variabelen ook zo generiek mogelijk te declareren. Dit bevordert de onderhoudbaarheid van je code.


[...]

Code met is of instanceOf achtige constructies zijn vaak (niet altijd) een bad smell. Kijk dan liever of je de check kunt verwijderen door een method call waarbij er gedispatcht wordt op de argument types.
Kijk .... hij begrijpt het.

Verwijderd

rainmaker2k schreef op maandag 26 februari 2007 @ 22:22:
[...]


Als jij je code goed geschreven hebt, dan heb je niet eens Rectangle specifieke methodes nodig en volstaat het misschien zelfs om een interface te gebruiken ipv het uitbreiden van een klasse.
Ligt eraan, zowel een auto als een vliegtuig zijn voertuigen. Echter een auto kan niet vliegen, maar een vliegtuig moet dat wel kunnen en deze kan ook rijden. Je zult voor het vliegtuig dus specifieke methoden moeten implementeren. Een interface gebruiken is onzin en overkill als je maar 1 type vliegtuig hebt dat kan vliegen.
prototype schreef op maandag 26 februari 2007 @ 22:22:
[...]

Maar dat is dus voor zover ik kan opmaken uit TS's verhaal niet relevant, en meer dan triviaal...

[...]

Nee, lees je maar eens in mbt type coercion bij generics ;) C# heeft geen wildcard , zou je moeten simuleren wat meer code zou vereisen. Daarom deed ik het even in java.
Ik doe al geen java meer sinds 1.3 ergens ;), maar ik blijf het niet overzichtelijk vinden. Vind ik trouwens ook niet van LINQ. Zal wel gewenning zijn :+

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 14:37

RayNbow

Kirika <3

Verwijderd schreef op maandag 26 februari 2007 @ 22:14:
[...]


Jij ook ff lezen en vooral ff MSDN coding guidelines erbij pakken. Die raadt namelijk "is" en "as" aan. Bekijk ze ook maar eens op IL niveau, dan zie je een geoptimaliseerde versie van wat jij normaal zelf doet.
Geef eens een link naar de guidelines, want ik heb geen idee waar je nu precies op doelt?
Wat is java generics trouwens onoverzichtelijk op deze manier. Kan je niet gewoon List<Shape> doen?
Nee, want List<Shape> is geen supertype, noch een subtype van List<Rectangle>.

Gerelateerd leesvoer:Het komt erop neer dat als List<Rectangle> een subtype was van List<Shape>, dat je type safety niet meer kan garanderen.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op maandag 26 februari 2007 @ 22:28:
[...]

Ik doe al geen java meer sinds 1.3 ergens ;), maar ik blijf het niet overzichtelijk vinden. Vind ik trouwens ook niet van LINQ. Zal wel gewenning zijn :+
Ik weet dus niet of dit ook opgaat voor C#, maar afaik is het een generics 'vraagstuk'. LINQ is overigens geweldig, maar 'k begin dan ook steeds meer fan te worden van functionele aspecten :)

Verwijderd

RayNbow schreef op maandag 26 februari 2007 @ 22:30:
[...]

Geef eens een link naar de guidelines, want ik heb geen idee waar je nu precies op doelt?


[...]

Nee, want List<Shape> is geen supertype, noch een subtype van List<Rectangle>.

Gerelateerd leesvoer:Het komt erop neer dat als List<Rectangle> een subtype was van List<Shape>, dat je type safety niet meer kan garanderen.
Even snel de docs gescanned en ik zie maar 1 voordeel er in en dat is de type safety van de complete lijst dat je er maar elementen van 1 subtype in mag gooien. Dat is inderdaad wel een handige feature die in C# onbreekt.

Verwijderd

@TS

Zit je toevallig op de NHL en is dit voor de laatste Design Patterns opdracht? >:)

Verwijderd

Topicstarter
Verwijderd schreef op dinsdag 27 februari 2007 @ 01:44:
@TS

Zit je toevallig op de NHL en is dit voor de laatste Design Patterns opdracht? >:)
Nee, eigenlijk niet, het was meer iets waar ik zelf tegen aan liep. Maar jij dus wél? ;)

Het topic is trouwens wel erg interessant om te lezen zo ;) thanks for all input.

Nog even een vraagje ter verdieping. Als ik een class heb met public properties, en daarna deze extend, kan ik dan de properties private maken zodat ze gehide worden?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class MyShape
{
    private string _myOldString = "My Old String";
    public string MyOldString
    {
        get { return _myOldString; }
        set { _myOldString = value; }
    }
}

class MyRectangle : MyShape
{
    public string MyNewString
    {
        get { return base.MyOldString; }
        set { base.MyOldString = value; }
    }

    private new string MyOldString
    {
        get { return base.MyOldString; }
        set { throw new Exception(); }
    }

}

class Program
{
    static void Main(string[] args)
    {
        MyRectangle rect = new MyRectangle();
        Console.WriteLine("MyRectangleString: " + rect.MyNewString);  // returns: My Old String
        Console.WriteLine("MyShapeString: " + rect.MyOldString);      // returns: My Old String
        // De bovenstaande had NIET moeten kunnnen :-(
        
        rect.MyOldString = "Should not be allowed"; // <-- Deze wil ik NIET kunnen benaderen, eigenlijk niet kunnen zien
        Console.WriteLine("MyShapeString: " + rect.MyOldString);          // returns: Should not be allowed
        
        rect.MyNewString = "NEW string";
        Console.WriteLine("MyRectangleString: " + rect.MyNewString);  // returns: NEW string
        
        Console.ReadKey();
    }
}


Daarnaast heb ik ook nog een boel andere combinaties geprobeerd zonder resultaat... Gewoon niet mogelijk dan?

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Als ik een class heb met public properties, en daarna deze extend, kan ik dan de properties private maken zodat ze gehide worden?
Nee.
Waarom zou je dat willen doen dan ? Wil je dan gewoon niet protected ?
Ik denk dat, als je dergelijke dingen wilt, je nog eens moet nadenken over je class - design.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op donderdag 01 maart 2007 @ 12:43:
[...]

Nee.
Waarom zou je dat willen doen dan ? Wil je dan gewoon niet protected ?
Ik denk dat, als je dergelijke dingen wilt, je nog eens moet nadenken over je class - design.
Ik erf over van een bestaande .NET class, en die heeft een property "Children", echter wil ik de class uitbreiden met functionaliteit, zodat ik meer controle kan uitoefenen op deze property. Alleen wil ik voor een aantal classes die ik extend, de benaming en functionaliteit gelijktrekken, en wil dus voor de classes waar het "Content" en waar het "Children" heet, dezelfde naam gaan gebruiken. Het liefst wil ik dan ook de oude naam voor overzichtelijkheid gewoon verbergen voor iedereen van buitenaf.

Zodra ik beide aliasen van elkaar laat zijn, waarbij "Content" en "Children" gelijke implementatie krijgen, is er geen probleem, maar daar wordt het geheel zo onoverzichtelijk van...

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op donderdag 01 maart 2007 @ 12:55:
[...]

Ik erf over van een bestaande .NET class, en die heeft een property "Children", echter wil ik de class uitbreiden met functionaliteit, zodat ik meer controle kan uitoefenen op deze property. Alleen wil ik voor een aantal classes die ik extend, de benaming en functionaliteit gelijktrekken, en wil dus voor de classes waar het "Content" en waar het "Children" heet, dezelfde naam gaan gebruiken. Het liefst wil ik dan ook de oude naam voor overzichtelijkheid gewoon verbergen voor iedereen van buitenaf.
verbergen kan niet, want je kunt altijd casten naar het supertype, en die heeft de property. Een subtype is-a supertype, dus MOET de public members hebben van supertype.
Zodra ik beide aliasen van elkaar laat zijn, waarbij "Content" en "Children" gelijke implementatie krijgen, is er geen probleem, maar daar wordt het geheel zo onoverzichtelijk van...
Je zou kunnen overwegen een interface te definieren die Content heeft en geen children. In je code gebruik je dan die interface en de interface implementatie van Content returned gewoon this.Children.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

EfBe schreef op donderdag 01 maart 2007 @ 13:04:
[...]

verbergen kan niet, want je kunt altijd casten naar het supertype, en die heeft de property. Een subtype is-a supertype, dus MOET de public members hebben van supertype.


[...]

Je zou kunnen overwegen een interface te definieren die Content heeft en geen children. In je code gebruik je dan die interface en de interface implementatie van Content returned gewoon this.Children.
Mwha, je zou "new" kunnen gebruiken als je het echt zou willen, maar ik huiver eigenlijk al zodra ik weer eens ergens "new" zie staan... Dat hide natuurlijk helemaal niets :')

[ Voor 3% gewijzigd door Verwijderd op 01-03-2007 18:53 ]

Pagina: 1