Avatar billede -benne- Nybegynder
02. november 2005 - 07:52 Der er 23 kommentarer og
2 løsninger

C#, pointers, clonings m.m.

Oplevede en interessant problematik da jeg sad og arbejdede på et større projekt med en masse ref's og andet sjov i aftes...
Jeg ved godt at egentlige pointers i C# er noget unsafe fybæ, men hvordan så?

Hvornår "kloner" C# et object og hvornår laver den en pointer til et objekt?

Der er forskellige problemstillinger jeg er bekendt med, f.eks.

private void test(Socket testSocket)
{
  // testSocket er en klon af socket parses til funktionen, med mindre ref bruges..
}

Men problemet er, og mit egentlige spørsmål er, hvornår klones objekter og hvornår oprettes der pointere til samme..

F.eks. hvis jeg selv har lavet et objekt ud fra en klasse:

TestClass classA = new TestClass();
TestClass classB;

classB = classA;

Alle ændringer jeg foretager med classA bliver også reflekteret i classB - er det pga. reflection eller fordi B bare er en pointer til A - oder was?

Envidere når jeg forsøger det samme med:

string A = "testA"; // eller String A;
string B = "testB"; // eller String B;

Så er der ingen reflektion, og disse operere hver for sig?

Hvornår træder første og anden "regel" i brug?
Avatar billede pidgeot Nybegynder
02. november 2005 - 08:09 #1
I C# (og de fleste andre sprog) skelnes mellem en value type og en reference type. En value type bliver altid sendt med til metoder som værdi (dvs. den bliver kopieret), mens en reference type bliver sendt med som en reference (dvs. du peger på et eksisterende objekt).

Som standard er alle simple typer (dvs. dem der kan bruges uden initialisering med new) value types. (Teknisk set er string ikke simpel, men den tager vi en anden dag.) Klasser er reference types.

Der er dog den undtagelse, der hedder en struct - i C# er der ingen forskel på en struct og en class, bortset fra at en struct altid er en value type. Dvs. at du kan sikre dig at dine objekter kopieres hvis du ændrer dem fra classes til structs.

Håber du blev lidt klogere af forklaringen :)
Avatar billede -benne- Nybegynder
02. november 2005 - 10:15 #2
Lækkert - jeg har nemlig haft nogle dilemma'er med at rette noget kode efter for andre, hvor netop brug og "kopiering" af sockets har været problematisk.. Men nu er alt gjort lidt klarer :)

Smid et svar...
Avatar billede arne_v Ekspert
02. november 2005 - 10:15 #3
bemærk at de slags typer:
  value typer = typer hvor variabel har værdien
  reference typer = typer hvor variablen peger på noget
og argumenter i kald:
  ingenting = by value
  angivelse af ref = by reference
er uafhængige af hinanden.
Avatar billede arne_v Ekspert
02. november 2005 - 10:16 #4
du kan sende en value type over by reference og en reference type over by value
Avatar billede arne_v Ekspert
02. november 2005 - 10:17 #5
reflection er noget helt andet end det her (nemlig hvordan man runtime loader
klasser og finder metoder i dem)
Avatar billede arne_v Ekspert
02. november 2005 - 10:18 #6
string A = "testA";
string B = A;

er teknisk set 2 variable som peger på det samme

men der er ingen metoder som kan ændre på en String så det er umuligt at bevise
Avatar billede -benne- Nybegynder
02. november 2005 - 10:19 #7
arne: Dvs. at hvis jeg laver noget hams med:

Socket testSocket = new Socket(...);

TestFunction(testSocket);

function TestFunction(Socket aSocket)
{
  //...
}

Så er det egentlig en reference der overføres, hvorimod at ref bare bruges til overføring af reference til en value type, f.eks. byte[]?
Avatar billede arne_v Ekspert
02. november 2005 - 10:19 #8
nej - du overfører en reference type by value
Avatar billede arne_v Ekspert
02. november 2005 - 10:20 #9
d.v.s. at du kan ændre i din Socket og ændringerne kan ses i koden udenfor

men hvis du sætter aSocket til at pege på en anden socket kan det ikke ses i
koden udenfor
Avatar billede arne_v Ekspert
02. november 2005 - 10:20 #10
kender du C/C++
Avatar billede -benne- Nybegynder
02. november 2005 - 10:22 #11
Ah, okai - men i ovenstående eksempel vil ændringer foretaget i socketen, i funktionen, vil afspejles uden for funktionen (indtil jeg overskriver socketen i funktionen med en ny instans)?
Avatar billede -benne- Nybegynder
02. november 2005 - 10:22 #12
Har arbejdet lidt med C/C++, men det er _længe_ siden.
Avatar billede arne_v Ekspert
02. november 2005 - 10:24 #13
ja
Avatar billede -benne- Nybegynder
02. november 2005 - 10:26 #14
Jeg tror vist at dit svar kvalificere sig til halvdelen af pointsne :)
Avatar billede pidgeot Nybegynder
02. november 2005 - 13:38 #15
Ja, smid du bare halvdelen over til Arne, har jeg det fint med :)
Avatar billede -benne- Nybegynder
02. november 2005 - 13:54 #16
Så mangler vi bare lige et svar fra Arne
Avatar billede arne_v Ekspert
02. november 2005 - 13:55 #17
kommer
Avatar billede runesoft Nybegynder
15. november 2005 - 09:02 #18
Man kan ikke overføre en reference type over by value. Jeg synes at kalde det at overføre en reference type by value er forkert. hvis du bruger ref på en referencetype får du en reference til en reference, det er således muligt at skifte en streng ud.

http://dotnetexception.blogspot.com/2005/11/byref-vs.html
Avatar billede arne_v Ekspert
15. november 2005 - 09:13 #19
default er at sende en reference over by value

du har:
  value typer by value (f.eks. int uden ref)
  value typer by reference (f.eks. int med ref)
  reference typer by value (f.eks. string uden ref)
  reference typer by reference (f.eks. string med ref)

svarende til C++:

int
int&
int*
int*&

og bloggen er forkert - termerne by value og by reference har helt præcise
veldefinerede betydninger som er ældre end både .NET og Java - det hedder
by value og by reference
Avatar billede runesoft Nybegynder
15. november 2005 - 09:52 #20
det ændrer ikke på at by value i .Net betyder værdien af variablen som er en reference. Det giver sgu da ingen mening...  I Java dokumentation står der at reference typer bliver overført by reference, og det er det samme der sker.

Når jeg bruger ordet by value, forventer jeg at indholdet af mit objekt bliver kopieret...  det gør det ikke

.Net bruger det anderledes end Java!
Avatar billede runesoft Nybegynder
15. november 2005 - 09:54 #21
med en reference forstår jeg det der svarer til en pointer, bare uden selv at kunne sætte den. ref på objekter i .Net svarer til det jeg kender som pointer til en pointer i C++.
Avatar billede arne_v Ekspert
15. november 2005 - 11:48 #22
hvis der i java dokumentationen står at "reference typer bliver overført by reference",
så er det en fejl - java kan kun overføre by value - det kan du finde udførligt
beskrevet masser af steder - har du et link til den dokumentation du henviser til ?

og man kan ikke ændre på betydningen af termer som "by value" og "by reference"
der har eksisteret i 30-40 år

man kan muligvis klandre både .NET og Java for at have valgt den lidt
kryptiske "reference typer" som godt kan give de forkerte associationer

ikke mindst fordi en reference type by value gør det som mange tror at
by reference drejer sig om - og jeg har sikkert også selv udtalt
"java sender ikke-simple typer over by reference"

----

C int** svarer stort set til C++ int*&, men jeg synes at den sidste mere præcist
beskriver hvad man vil (int** kan også bruges i andre sammenhænge som
f.eks. et 2D jigsaw array)
Avatar billede runesoft Nybegynder
15. november 2005 - 12:38 #23
Vi er ude i noget langt ude ordkløveri.

Java overfører objecter som reference og simple typer som værdier. Alle jeg kender der har læst om det har forstået disse koncepter med det samme. Java certificeringerne går meget op i dette.

.net overfører simple typer som værdier og objecter som referencer(ligesom Java). Derudover kan man vælge at ville overføre "by reference" som for simple typer betyder en reference, og som for objecter betyder en reference til den reference man havde i forvejen.

Vi er enige om hvad der sker. Det eneste jeg ikke kan lide er .net's dokumentation, altså at når man overfører et object "by value", så får man overført en reference. Jeg har mødt personer der overfører parametre byref for at performance optimere sin kode...
Avatar billede arne_v Ekspert
15. november 2005 - 12:53 #24
jeg synes at både .NET og Java terminologien er meget passende

når man overfører en reference by value, så kan man da ikke kalde det noget
andet end det er
Avatar billede arne_v Ekspert
15. november 2005 - 12:54 #25
og jeg vil stadigvæk gerne have et link til "I Java dokumentation står der at reference
typer bliver overført by reference"
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
Kurser inden for grundlæggende programmering

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