Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#] Structure data tussen verschillende classes

Pagina: 1
Acties:
  • 172 views sinds 30-01-2008
  • Reageer

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ik heb al een tijdje gezocht op internet en heb ook in dit forum lopen zoeken.
Maar ik krijg nergens duidelijkheid over wat nou de beste manier is om data vanuit een ene class naar een andere te brengen.

Ik heb een class gemaakt met daarin een structure en een method die de structure vult.
Hoe kan ik nu het beste de data uit deze structure beschikbaar maken voor een andere class?

Als dit een basic vraag is willen jullie me dan op zijn minst wijzen waar ik naar moet zoeken.
Mijn leraar kwam gaf de hint dat ik een gridview moest gebruiken?
Maar als ik het zo zie is dit iets voor een online applicatie?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je kunt een structure toch gewoon doorgeven aan een andere class?
Gehakt schreef op maandag 19 november 2007 @ 11:06:
Mijn leraar kwam gaf de hint dat ik een gridview moest gebruiken?
:D :') _O-
Seriously: :X
Gehakt schreef op maandag 19 november 2007 @ 11:06:
Maar als ik het zo zie is dit iets voor een online applicatie?
Een gridview is niets anders dan een weergave van 'cellen' (een grid). Die zijn er niet alleen 'online' maar ook in offline varianten.

[ Voor 97% gewijzigd door RobIII op 19-11-2007 11:10 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • whoami
  • Registratie: December 2000
  • Laatst online: 29-11 22:54
Je kan informatie toch gewoon aan een andere class doorgeven dmv een method of een property ?
Mijn leraar kwam gaf de hint dat ik een gridview moest gebruiken?
Ik zie niet in waar dit zou kunnen helpen om informatie tussen classes door te gaan geven ?
Misschien moet die leraar maar eens een ander vak gaan geven ofzo...

[ Voor 56% gewijzigd door whoami op 19-11-2007 11:10 ]

https://fgheysels.github.io/


  • gorgi_19
  • Registratie: Mei 2002
  • Nu online

gorgi_19

Kruimeltjes zijn weer op :9

whoami schreef op maandag 19 november 2007 @ 11:09:
Je kan informatie toch gewoon aan een andere class doorgeven dmv een method of een property ?


[...]
Ik zie niet in waar dit zou kunnen helpen om informatie tussen classes door te gaan geven ?
Misschien moet die leraar maar eens een ander vak gaan geven ofzo...
Je kan allicht een gridview maken, vullen, deze doorgeven aan de andere class, die hem vervolgens weer uitleest? :? :+

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • sig69
  • Registratie: Mei 2002
  • Nu online
Ik zit me eigenlijk af te vragen of de vraagstelling van de topic starter hier wel klopt, kan me niet voorstellen dat die leraar dit echt in deze context voor zou stellen. Ok, het niveau van leraren is soms bedroevend, maar zo erg heb ik ze nog niet gezien...

Roomba E5 te koop


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
offtopic:
Ik wil niet noodzakelijk de leraar verdedigen, maar mogelijk heeft de TS het commentaar van de leraar verkeerd begrepen? We missen nogal wat context. I know, I know, leraren zijn evil en dom, maar toch :+

edit:
spuit 11 ;)

[ Voor 5% gewijzigd door bigbeng op 19-11-2007 11:15 ]


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Euhm jah hoe dan? :?

Ik heb nu zoiets:

code:
1
2
3
4
5
6
7
8
9
class Elf
{
        [StructLayout(LayoutKind.Explicit, Size = 54)]
        internal struct ElfHeader
        {...}

        public static int Reader(string FileName)
        {...}
}

Hiernaast nog de Form1 class (gui).
Waarin ik de Elf.Reader() method aanroep die de structure vult.

Of sla ik nu de plank echt ergens heel erg mis en kan ik het op een betere manier oplossen?

De leraar vond dit een goede oplossing doordat de data in een gridview voor verschillende classes toegangelijke was.

Ik zit op een embedded systems opleiding en de hier word voornamelijk met C geprogrammeerd en niet C# dus hoe hoog het niveau van de leraar is met betrekking tot C# weet ik niet. Allicht hoger dan dat van mij.

[ Voor 27% gewijzigd door Gehakt op 19-11-2007 11:18 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Oei, toch dommer dan ik dacht. Gridviews brengen ook een overhead met zich mee en zijn zeker niet bedoeld als datauitwisselingsmechanisme.
Als meerdere klasses over data uit een bepaalde klasse moeten kunnen beschikken, dan gebruik je normaalgesproken public properties en methods.

Als de struct publiek moet zijn, waarom maak je hem dan niet public? M.a.w. niet een internal struct, maar gewoon een public struct?

edit:
even terminologie gelijkgetrokken class != struct :)

[ Voor 15% gewijzigd door bigbeng op 19-11-2007 11:25 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
As said, je kunt een structure net zo goed passen van A naar B als een string, int of andere class. Moet je 'm wel public maken.
edit:

Code voorbeeld toch maar verwijderd. Wil niet té veel voorkauwen ;)

[ Voor 159% gewijzigd door RobIII op 19-11-2007 11:27 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Wij gebruiken meestal structures voor simpele data structuren en classes voor de wat complexere structuren een class. Bedenk wel dat een strcuture (struct) altijd als kopie wordt doorgegeven tenzij het 'ref' keyword wordt gebruikt.

Wij hebben als stelregel dat als een methode meer dan 4 argumenten nodig heeft, de argumenten middels een structure doorgegeven moeten worden of de argumenten als properties gezet moeten worden.

Een object met in zijn naam 'view' behoort een presentatie object te zijn en behoort daardoor dus niet als data holder gebruikt te worden.

If it isn't broken, fix it until it is..


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:17
Gehakt schreef op maandag 19 november 2007 @ 11:15:
Ik zit op een embedded systems opleiding en de hier word voornamelijk met C geprogrammeerd en niet C# dus hoe hoog het niveau van de leraar is met betrekking tot C# weet ik niet. Allicht hoger dan dat van mij.
Dat is geen enkel excuus als de leraar inderdaad dit advies heeft gegeven; het heeft nl weinig met de taal an sich te maken maar meer met applicatie design in het algemeen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Niemand_Anders schreef op maandag 19 november 2007 @ 11:33:
Wij gebruiken meestal structures voor simpele data structuren en classes voor de wat complexere structuren een class. Bedenk wel dat een strcuture (struct) altijd als kopie wordt doorgegeven tenzij het 'ref' keyword wordt gebruikt.
Structs hebben nergens zin behalve voor immutable value types, dus bv complex number. Zodra je data gaat muteren in een struct is een class beter. Dus jouw regel is onzin, het gaat nl. niet over 'simpel', maar over het niet muteerbaar zijn.
Wij hebben als stelregel dat als een methode meer dan 4 argumenten nodig heeft, de argumenten middels een structure doorgegeven moeten worden of de argumenten als properties gezet moeten worden.
Wat is dat voor onzinnige regel! De overload feature is dan weg, naast het feit dat de compiler checkt of je wel de juiste parameters doorgeeft.
Gehakt schreef op maandag 19 november 2007 @ 11:06:
Ik heb al een tijdje gezocht op internet en heb ook in dit forum lopen zoeken.
Maar ik krijg nergens duidelijkheid over wat nou de beste manier is om data vanuit een ene class naar een andere te brengen.
Wat is de semantische waarde van de data? Als die data zn semantische waarde ontleent aan het object waar de data in zit, dan is het niet echt nuttig data te copieren, je moet dan eerder een reference.
Ik heb een class gemaakt met daarin een structure en een method die de structure vult.
Hoe kan ik nu het beste de data uit deze structure beschikbaar maken voor een andere class?
Dat heet het aggregate pattern. Daar maar eens op zoeken.

Verder is het gebruik van struct af te raden, wanneer de data gemuteerd gaat worden IN de struct instance.

[ Voor 31% gewijzigd door EfBe op 19-11-2007 12:08 ]

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


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Schieten is leuk EfBe, maar het helpt als je dit soort commentaren bijstaat met wat referentiemateriaal. Dit geeft iemand die "foute" comments ook de kans om zichzelf te verbeteren. Zoals bijvoorbeeld dit stuk op de MSDN site over value types:
http://msdn2.microsoft.co...rary/y23b5415(vs.71).aspx

  • EfBe
  • Registratie: Januari 2000
  • Niet online
bigbeng schreef op maandag 19 november 2007 @ 12:47:
Schieten is leuk EfBe, maar het helpt als je dit soort commentaren bijstaat met wat referentiemateriaal. Dit geeft iemand die "foute" comments ook de kans om zichzelf te verbeteren. Zoals bijvoorbeeld dit stuk op de MSDN site over value types:
http://msdn2.microsoft.co...rary/y23b5415(vs.71).aspx
Een valuetype die mutable is is geen value type meer. DENK na over wat een value type is: het is NIET de struct instance, maar de value IN de struct instance, echter de value gebruiken houdt in dat je de struct instance juist gebruikt (zie: int, float etc.)

Door een mutable struct te hebben, heb je dus een value type die vervangen kan worden in het doosje waar hij in zit, terwijl het doosje (de struct) de value type representeert (immers, het is een value type!).

M.a.w.: het muteren van value typed instances is hetzelfde als het geheel vervangen door een nieuwe instance, en dus moeten structs immutable zijn.

Daarnaast zijn structs nare dingen wanneer je ze mutable maakt. Voorbeeld:
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
// Jeffrey Richter's book
using System;

interface IChangeable
  { void Change(int v); }

struct S : IChangeable
{
  int _v;

  public S(int v)
    { _v = v; }

  public void Change(int v)
    { _v = v; }

  public override string ToString()
    { return _v.ToString(); }
}

public class BoxingExample
{
  static void Main()
  {
    S s = new S(3);

    Object boxed = s;
    // One might expect the value in 'boxed'
    // to always be 3 after this point.

    ((IChangeable) boxed).Change(4);

    // But the next line prints "4"!!
    Console.WriteLine("boxed={0}", boxed);
  }
}


Er zijn wel meer voorbeelden hiervan, ArrayList van structs waarbij je een field wijzigt en dat lukt niet, want het compileert niet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public struct Foo
{
    public Foo(int i)
    {
        this.Bar = i;
    }
    
    public int Bar;
}

//....
ArrayList l = new ArrayList();
l.Add(new Foo(1));
l.Add(new Foo(2));
l.Add(new Foo(3));

Console.WriteLine("Before: {0}", ((Foo)l[0]).Bar);
((Foo)l[0]).Bar = 4;    /// compile error!
Console.WriteLine("After: {0}", ((Foo)l[0]).Bar);

Compileert niet.

Dit helpt ook niet:
Foo f = (Foo)[0];
f.Bar = 4;

want je muteert een value type! (== copy!)

Overigens staat als punt 3 in de link die jij plaatst: "[Structs] Are immutable.". Waarom moet ik dan iets aandragen om het aan te tonen, terwijl het gewoon in de MSDN staat?

[ Voor 19% gewijzigd door EfBe op 19-11-2007 13:27 ]

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


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Je droeg de link naar de MSDN niet aan om je argument kracht bij te zetten, daar doelde ik op. Ik snap dat jij als ervaren dotnetter MSDN als basiskennis ziet, maar niet iedereen is zo ervaren (of gebruikt MSDN zo intensief). Nofi verder, het is gewoon mijn manier van doen om naast te vertellen hoe het moet, ook te vertellen waarom mijn manier de beste is ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dus bijvoorbeeld een vector type met een public x, y en z properties mag geen struct zijn? Kom op zeg... Het is nogal wiedes dat boxed structs geen refentie zijn naar het origineel, eigenlijk moet je ze dus ook gewoon niet boxen.

.edit: grappig trouwens dat MS niet aan z'n eigen guidelines voldoet: http://msdn2.microsoft.co...work.vector3_members.aspx :Y)

[ Voor 63% gewijzigd door .oisyn op 20-11-2007 12:06 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

In dit geval mag je meteen even uitleggen waarom Microsoft de grootte van een struct (aanbevolen) op maximaal 16 bytes stelt. Waaruit volgt dit? Waarom niet 8 bytes, de grootte van een adres op de stack. Het lijkt me dat als een by value type efficienter moet zijn dan een reference type dat de grootte van het value type kleiner is dan de grootte van een adres op de stack?

Of blaat ik nu heel erg dom }:O

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja. Een extra indirectie door de reference is namelijk een stuk duurder dan wat extra bytes die toch al in de cache staan (want ze zijn op de stack gepushed en je accessed doorgaans ook data die eromheen staat)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Ja
Oke, duidelijk :)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
.oisyn schreef op dinsdag 20 november 2007 @ 11:56:
Dus bijvoorbeeld een vector type met een public x, y en z properties mag geen struct zijn? Kom op zeg... Het is nogal wiedes dat boxed structs geen refentie zijn naar het origineel, eigenlijk moet je ze dus ook gewoon niet boxen.
Natuurlijk mag het wel een struct zijn. Je moet het alleen immutable maken. Dus de CTor zet x, y en z en de properties / fields zijn readonly.

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


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ok om maar weer even 30 niveau's naar beneden te springen?
Waarom lukt het mij niet om e_ident van de struct te bereiken van uit een andere class?
code:
1
2
3
4
5
6
7
[StructLayout(LayoutKind.Explicit, Size = 54)]
        public static struct ElfHeader
        {
            [FieldOffset(0)]
            public byte e_ident;
            (etc bladiebla)
        }


Elf.ElfHeader word gewoon gezien in de andere class maar niet de variabelen die erin zitten?
Daarnaast vroeg ik mij af of de struct zoiezo wel bestaat? Want hij word pas aangemaakt in de functie Elf.reader()?
code:
1
2
3
4
5
6
7
8
9
public static int reader(string fileName)
        {
            (...code...)
            // Maak een nieuwe instantie van de ElfHeader 
            ElfHeader elfHeader = new ElfHeader();
            (...code...)
            return 0;
        }
    }

En ik heb er ondertussen maar een boek bijgepakt. Leert denk ik toch iets sneller dan van alleen internet.

  • FTL
  • Registratie: Maart 2000
  • Laatst online: 15:20

FTL

EfBe schreef op maandag 19 november 2007 @ 13:17:
[...]

Door een mutable struct te hebben, heb je dus een value type die vervangen kan worden in het doosje waar hij in zit, terwijl het doosje (de struct) de value type representeert (immers, het is een value type!).

M.a.w.: het muteren van value typed instances is hetzelfde als het geheel vervangen door een nieuwe instance, en dus moeten structs immutable zijn.
Interessant, om Point voorbeeld aan te halen.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Point
{
   public int _x;
   public int _y;
   public int _z;
   
   public Point(int x, int y, int z)
   {
       _x = x;
       _y = y;
       _z = z;
   }
}

Point p1 = new Point(1,2,3);
p1._x = 10;


De laatste regel zal toch alleen de value van _x van deze struct instantie op de stack veranderen?
Heb je meer info hierover?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 00:17
FTL schreef op dinsdag 20 november 2007 @ 14:39:
De laatste regel zal toch alleen de value van _x van deze struct instantie op de stack veranderen?
Heb je meer info hierover?
Natuurlijk, maar EfBe's punt is dat een struct op een dergelijke manier gebruikt eigenlijk geen value type meer is, omdat een value type identiek hoort te zijn voor en na een functieaanroep.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Point
{
   private int _x;
   private int _y;
   private int _z;
   
   public Point(int x, int y, int z)
   {
       _x = x;
       _y = y;
       _z = z;
   }
   public X { get; }
   public Y { get; }
   public Z { get; }
}


Dit zou dus beter zijn, omdat de struct nu immutable is, of zie ik het verkeerd?

@TS:
Ik zie:
code:
1
public static struct ElfHeader

Implementeer hem eens als:
code:
1
public struct ElfHeader

[ Voor 29% gewijzigd door Verwijderd op 20-11-2007 16:02 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op dinsdag 20 november 2007 @ 15:43:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Point
{
   private int _x;
   private int _y;
   private int _z;
   
   public Point(int x, int y, int z)
   {
       _x = x;
       _y = y;
       _z = z;
   }
   public X { get; }
   public Y { get; }
   public Z { get; }
}


Dit zou dus beter zijn, omdat de struct nu immutable is, of zie ik het verkeerd?
Precies. Als jij Point p.X wijzigt, is dat dan hetzelfde Point met een andere X of een ander point? :) Daarom is immutable beter.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik blijf het onzin vinden. Waarom zou de Point nog hetzelfde zijn als je de x wijzigt? Waarom is een int nog hetzelfde als je 'm een nieuwe waarde toekent? Ik zie het verschil niet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik vermoed dat het hier vooral gaat om het feit dat bij wijzigbaarheid een struct wel erg op een class gaat lijken, behalve dat je hem expliciet als ref moet meegeven als je hem bijvoorbeeld in een functie wil wijzigen. M.a.w. op die manier wordt een struct een class met "vreemd gedrag".

Puristisch gezien is een struct in .Net dus een atomaire waarde, dus moet je hem ook atomair toekennen, als in alle onderdelen in 1 keer. Je zegt bij een decimal ook niet x = 1.0 en dan x.GetalAchterDeKomma = 12. Een beetje lame voorbeeld, maar ik kon even niet met iets beters komen :)

Ik hoop dat ik dit een beetje juist verwoord.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Microsoft hanteerd die stelregel trouwens zelf ook niet in het .net framework. Een System.Drawing.Point kun je ook gewoon muteren.

Tuurlijk moet je wel op passen met wat je doet, en Structs zijn vaak inderdaad datatypes die niet mutable zijn. Maar om het nou zo te stellen dat je en struct nooit zou mogen muteren vind ik ook wel erg ver gaan.

“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.”


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

bigbeng schreef op dinsdag 20 november 2007 @ 16:44:
Ik vermoed dat het hier vooral gaat om het feit dat bij wijzigbaarheid een struct wel erg op een class gaat lijken, behalve dat je hem expliciet als ref moet meegeven als je hem bijvoorbeeld in een functie wil wijzigen. M.a.w. op die manier wordt een struct een class met "vreemd gedrag".
Zo'n reactie had ik idd al verwacht, maar mijn vraag is dan: waarom is een class geen struct met "vreemd gedrag"? Waarom niet gewoon accepteren dat een class (ref type) en een struct (value type) verschillende dingen zijn met verschillende semantiek, maar (wellicht jammer genoeg) met dezelfde syntax (in C# en VB dan)?

[ Voor 16% gewijzigd door .oisyn op 20-11-2007 16:58 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
.oisyn schreef op dinsdag 20 november 2007 @ 16:54:
[...]

Zo'n reactie had ik idd al verwacht, maar mijn vraag is dan: waarom is een class geen struct met "vreemd gedrag"? Waarom niet gewoon accepteren dat een class (ref type) en een struct (value type) verschillende dingen zijn met verschillende semantiek, maar (wellicht jammer genoeg) met dezelfde syntax?
Eens. Daarom zette ik vreemd gedrag ook tussen quotes. Het is idd gewoon logisch gedrag vanuit de semantiek gezien. Ik vermoed dan ook dat dit soort discussies uitmonden in een welles-nietes verhaal omdat mensen een ander idee hebben bij "waar is een struct voor bedoeld".

  • EfBe
  • Registratie: Januari 2000
  • Niet online
.oisyn schreef op dinsdag 20 november 2007 @ 16:54:
[...]

Zo'n reactie had ik idd al verwacht, maar mijn vraag is dan: waarom is een class geen struct met "vreemd gedrag"? Waarom niet gewoon accepteren dat een class (ref type) en een struct (value type) verschillende dingen zijn met verschillende semantiek, maar (wellicht jammer genoeg) met dezelfde syntax (in C# en VB dan)?
Accepteren prima, maar omdat de code er hetzelfde uitziet lijkt het alsof een struct type hetzelfde kan worden gebruikt als een class type en dat is dus niet het geval.

Foo f = GetFoo(id);
f.Bar++;

Deze code ziet er voor struct of class Foo hetzelfde uit, maar wanneer Foo een struct is, betekent f.Bar++ semantisch iets heel anders dan bij een class type Foo.

De discussie is ong. gelijk aan de discussie of je een PK value van een row in een table moet kunnen wijzigen of niet: semantisch kan dat niet, want wijzigen betekent een nieuwe instance. :)

In C++ is het verschil minimaal geloof ik (op visibility van members na), dus wellicht dat je daardoor de discussie wat raar vindt. ;). In .NET talen als C# is het echt een fundamenteel probleem wat vaak tot problemen leidt.

[ Voor 10% gewijzigd door EfBe op 20-11-2007 18:57 ]

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


Verwijderd

it het 70-536 boek
■ Logically represents a single value

■ Has an instance size less than 16 bytes

■ Will not be changed after creation

■ Will not be cast to a reference type
Even daarvoor een dergelijk voorbeeld:
C#:
1
2
3
4
5
6
7
8
9
10
11
            System.Drawing.Point p = new System.Drawing.Point(10, 20);
            
            Console.WriteLine("x: {0}, y {1}:", p.X, p.Y);

            p.X = 15;

            Console.WriteLine("x: {0}, y {1}:", p.X, p.Y);

            p.Offset(-1, -1);

            Console.WriteLine("x: {0}, y {1}:", p.X, p.Y);

[ Voor 28% gewijzigd door Verwijderd op 20-11-2007 20:29 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

EfBe schreef op dinsdag 20 november 2007 @ 18:55:
[...]

Accepteren prima, maar omdat de code er hetzelfde uitziet lijkt het alsof een struct type hetzelfde kan worden gebruikt als een class type en dat is dus niet het geval.

Foo f = GetFoo(id);
f.Bar++;
Ik snap je punt, maar snap je mijn punt dat je het net zo goed ook om kan draaien? :). Goed, 't is natuurlijk wat minder praktisch als bij een ref type altijd een copy wordt gemaakt als je assignt
Deze code ziet er voor struct of class Foo hetzelfde uit, maar wanneer Foo een struct is, betekent f.Bar++ semantisch iets heel anders dan bij een class type Foo.
Nitpick: de f.Bar++ is semantisch hetzelfde (je verhoogt in beide gevallen de Bar van f), het is de Foo f = GetFoo(id) waar de discrepantie zit.
De discussie is ong. gelijk aan de discussie of je een PK value van een row in een table moet kunnen wijzigen of niet: semantisch kan dat niet, want wijzigen betekent een nieuwe instance. :)
Mja, hiermee begeef je je wel een beetje op glad ijs, want in principe moet je een PK sowieso niet willen wijzigen ;)
In C++ is het verschil minimaal geloof ik (op visibility van members na), dus wellicht dat je daardoor de discussie wat raar vindt. ;). In .NET talen als C# is het echt een fundamenteel probleem wat vaak tot problemen leidt.
Nou trek ik de class en struct van C# niet gelijk met de class en struct van C++ hoor. In C++ zijn dat idd gewoon dezelfde dingen. Maar laten we voor het gemak dan even C++/CLI erbij pakken, waarmee je gewoon .Net code kunt schrijven. Daar heb je een 'ref class' en 'value class' om resp. ref types en value types mee te definieren (en het keyword 'class' kun je in C++/CLI dan weer evt. vervangen voor struct om de default visibility te wijzigen). Het grappige is echter, beide typen kun je behandelen als een reference type en als een value type. Je kunt een ref class als lokale var op de "stack" aanmaken (in feiten is dit echter niet op de stack want dat laat de .Net VM immers niet toe, maar semantisch werkt het wel zo) en value classes kun je gewoon dynamisch alloceren op de heap (inclusief alle GC van dien). Het verschil tussen een C++/CLI ref class en een normale C++ class is dat een ref class geen automatisch gegenereerde copy ctor en assignment operator heeft gedefinieerd - wat logisch is aangezien het niet gebruikelijk is dat je ze kopiëert.

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
value struct MyValueType
{
    int i;
};

ref struct MyRefType
{
    int i;

    MyRefType() { }
    MyRefType(const MyRefType % other) { i = other.i; }
    MyRefType % operator=(const MyRefType % other) { i = other.i; return *this; }
};

int main()
{
    MyValueType valueOnStack1; // normal usage
    MyValueType ^ valueOnHeap1 = gcnew MyValueType(); // allowed

    MyValueType valueOnStack2 = valueOnStack1; // copy
    valueOnStack2.i = 10;
    System::Console::WriteLine(valueOnStack1.i); // still 0

    MyValueType ^ valueOnHeap2 = valueOnHeap1;
    valueOnHeap2->i = 10;
    System::Console::WriteLine(valueOnStack1->i); // changed to 10


    MyRefType refOnStack1; // allowed
    MyRefType ^ refOnHeap1 = gcnew MyRefType(); // normal usage

    MyRefType refOnStack2 = refOnStack1; // calls copy ctor
    refOnStack2.i = 10;
    System::Console::WriteLine(refOnStack1.i); // still 0

    MyRefType ^ refOnHeap2 = refOnHeap1;
    refOnHeap2->i = 10;
    System::Console::WriteLine(refOnHeap1->i); // changed to 10
}


In C++/CLI heb je dus duidelijk de distinctie in syntax tussen objecten zelf en referenties naar objecten.

note to self: C++/CLI highlighter maken voor GoT

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ok even een beste schop:

Ik heb 2 klassen gemaakt.
De struct bevind zich apart.
Ik wil de struct vanuit beiden klasse benaderen.

C#:
1
2
3
4
5
6
7
8
9
10
11
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Test blaat = new Test();
        }
    }
}


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace ConsoleApplication1
{
    public struct ElfHeader
    {
        public string structVariabele;
    } 


    public class Test
    {
        public Test()
        {
            ElfHeader testje;
            testje.structVariabele = "Gelukt";
        }
    }
}


Ik maak in de class Test de structure. Waarom kan ik deze dan niet benaderen vanuit de andere class?

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 15:18

mulder

ik spuug op het trottoir

Dat heeft met scope te maken, ff op MSDN oid kijken. Verder zou je om dit op te lossen een public property Testje kunnen maken, dus:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
    public class Test 
    { 
        ElfHeader testje;
        public Test() 
        { 
             
            testje.structVariabele = "Gelukt"; 
        } 
        public ElfHeader Testje
        {
            get{return testje;}
        }
    }

oogjes open, snaveltjes dicht


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 24-10 20:19
Ik had inderdaad wel het idee dath et met de scope te maken had.
Maar het is me eindelijk gelukt en de oplossing is heel simpel.
Op het moment dat het object ook daadwerkelijk aanmaakt moet je aangeven dat deze public is.
Zo dus:

C#:
1
public StructNaam structObject;

Verwijderd

Probeer het eens als volgt:
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
45
46
47
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    struct ElfHeader
    {
        private string elfHeaderString;

        public ElfHeader(string _elfHeader)
        {
            elfHeaderString = _elfHeader;
        }
        public string ElfHeaderString 
        { 
            get 
            { 
                return elfHeaderString; 
            }  
        }
    }
    
    class Test
    {
        private string elfHeaderStringValue;
        public string ElfHeaderStringValue { 
            get 
            { 
                return elfHeaderStringValue; 
            } 
            set 
            { 
                elfHeaderStringValue = value; 
            } 
        }
                
        public Test()
        {
            
            ElfHeader testje = new ElfHeader("Melp");
            elfHeaderStringValue = testje.ElfHeaderString;
        }
        
    }

}

En:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class NogEenTestje
    {
        public NogEenTestje()
        {
            Test test = new Test();
            Console.WriteLine("testwaarde: {0}", test.ElfHeaderStringValue);
        }

        public static void Main(string[] args)
        {
            new NogEenTestje();
            Console.ReadKey();
        }
    }
}
Pagina: 1