[C#2.0] Raar gedrag bij clone method

Pagina: 1
Acties:

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 01-12 20:46
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List<double>[] resultaat = new List<double>[2];
            
for (int i = 0; i < resultaat.Length; i++)
    resultaat[i] = new List<double>();
            
resultaat[0].Add(50.0);
resultaat[0].Add(80.0);
resultaat[1].Add(75.0);
resultaat[1].Add(123.0);
resultaat[1].Add(142.0);

List<double>[] res = resultaat.Clone() as List<double>[];

resultaat[0][0] = 51.0;

Debug.WriteLine(res[0][0]);


Output = 51

Ik had verwacht dat ik door het clonen wijzigingen kon aanbrengen zonder dat het effect zou hebben op de andere List, maar de waarden worden gelijkgetrokken, blijkbaar is het gewoon een pointer copy.

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
DrDelete schreef op maandag 23 april 2007 @ 16:24:
Ik had verwacht dat ik door het clonen wijzigingen kon aanbrengen zonder dat het effect zou hebben op de andere List, maar de waarden worden gelijkgetrokken, blijkbaar is het gewoon een pointer copy.
correct, clone neemt alleen simple types mee als echte kopie.
wanneer je wilt dat je attributen die niet simple types zijn ook gecloned worden moeten deze ook cloneble zijn, en moet je recursief clonen.

[ Voor 29% gewijzigd door BasieP op 23-04-2007 16:32 ]

This message was sent on 100% recyclable electrons.


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Tja, vzikw is er geen 'algemene regel' die beschrijft hoe 'Clone' moet werken in .NET; vandaar dat sommige classes niet echt een 'Clone' doen zoals je verwacht.

Kijk echter eens of je het niet kan oplossen dmv een specifieke constructor van List<>

Dit doet wat je wilt, maar, enkel als je value-types op je list gaat zetten:
code:
1
2
3
4
5
6
7
List<int> il = new List<int> ();
il.Add (5);
il.Add (4);
List<int> cil = new List<int> (il);
il[0] = 1;
Console.WriteLine (il[0].ToString());
Console.WriteLine (cil[0].ToString());


Eens je reference-types op je list zet, gaat het weer niet zoals jij wilt:
code:
1
2
3
4
5
6
7
8
9
10
11
List<Class1> l = new List<Class1> ();
l.Add (new Class1 (4));
l.Add (new Class1 (5));
l.Add (new Class1 (6));

List<Class1> copy = new List<Class1> (l);

l[0].Test = 1;

Console.WriteLine (l[0].Test.ToString ());
Console.WriteLine (copy[0].Test.ToString ());

[ Voor 55% gewijzigd door whoami op 23-04-2007 16:37 ]

https://fgheysels.github.io/


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 01:51
A shallow copy of an Array copies only the elements of the Array, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new Array point to the same objects that the references in the original Array point to.

In contrast, a deep copy of an Array copies the elements and everything directly or indirectly referenced by the elements.
Normaal gedrag dus, aangezien een List een reference type is.
Edit: ah, na het zelf nog een keer gelezen te hebben maakt zelfs dat niet uit...

[ Voor 7% gewijzigd door sig69 op 23-04-2007 16:34 ]

Roomba E5 te koop


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Toch gewoon een kwestie van ICloneable implementeren?

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


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 01-12 20:46
Helaas moet ik toch wat custom copy doen, dit heb ik er van gemaakt en het werkt nu goed:


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
List<double>[] resultaat = new List<double>[2];
            
for (int i = 0; i < resultaat.Length; i++)
  resultaat[i] = new List<double>();
            
resultaat[0].Add(50.0);
resultaat[0].Add(80.0);
resultaat[1].Add(75.0);
resultaat[1].Add(123.0);
resultaat[1].Add(142.0);

List<double>[] res = new List<double>[resultaat.GetLength(0)];
for (int i = 0; i < resultaat.GetLength(0); i++)
{
  res[i] = new List<double>();
  res[i].AddRange(resultaat[i]);
}

res[0][0] = 51.0;

Debug.WriteLine(resultaat[0][0]);

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
RobIII schreef op maandag 23 april 2007 @ 16:38:
Toch gewoon een kwestie van ICloneable implementeren?
Dat kan, en het zou makkelijk zijn moest er in C# copy constructors ondersteunen. :(

Nouja, je kan een object wel gaan 'deep-clonen' door het te serializen/deserializen. Maar, dan moet je je classes wel als serializable markeren.

[ Voor 23% gewijzigd door whoami op 24-04-2007 00:06 ]

https://fgheysels.github.io/


  • Koppensneller
  • Registratie: April 2002
  • Laatst online: 01-12 16:01

Koppensneller

winterrrrrr

sig69 schreef op maandag 23 april 2007 @ 16:32:
[...]

Normaal gedrag dus, aangezien een List een reference type is.
Edit: ah, na het zelf nog een keer gelezen te hebben maakt zelfs dat niet uit...
Nee, omdat de objecten in de List een reference type zijn. Als je een List<int> gebruikt zou het wel werken zoals je verwachtte.

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

dit artikel is misschien interresant.

Nu met Land Rover Series 3 en Defender 90


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 01-12 20:46
MTWZZ schreef op maandag 23 april 2007 @ 18:23:
dit artikel is misschien interresant.
thanx MTWZZ, interessant artikel!
Pagina: 1