.NET Forum / .NET Framework / New Users / August 2005
MyClass2 = MyClass1 -> ByRef????
|
|
Thread rating:  |
DraguVaso - 10 Aug 2005 16:44 GMT Hi,
I have 2 instances of a user-defined class. When I do a cls2 = cls1, and I change a property of cls2, this property is also changed in my cls1!!
Does anybody know what the reason of this is? and how I can prevent it?
Thanks,
Pieter
I'm using VB.NET 2003.
This is my sample code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim cls1 As New clsMyClass Dim cls2 As clsMyClass cls2 = Nothing cls2 = cls1 MessageBox.Show(cls1.Icon Is Nothing) Dim bmp As New Bitmap(20, 20, Imaging.PixelFormat.Format32bppPArgb) cls2.Icon = bmp MessageBox.Show(cls1.Icon Is Nothing) End Sub
Public Class clsMyClass Private m_Icon As Bitmap
Public Property Icon() As Bitmap Get Return m_Icon End Get Set(ByVal Value As Bitmap) m_Icon = Value End Set End Property
End Class
ThunderMusic - 10 Aug 2005 17:06 GMT Hi, There are probably many ways to accomplish this, but one way to prevent it would be to use a copy constructor like this: (That should do the trick)
Public Class clsMyClass Private m_Icon As Bitmap
Public Sub New() 'Do nothing for now, but you can add your code to it End Sub
Public Sub New(ByVal ClsToCopy as clsMyClass) Me.Icon = ClsToCopy.Icon End Sub
Public Property Icon() As Bitmap Get Return m_Icon End Get Set(ByVal Value As Bitmap) m_Icon = Value End Set End Property
End Class
> Hi, > [quoted text clipped - 36 lines] > > End Class Oenone - 10 Aug 2005 17:08 GMT > I have 2 instances of a user-defined class. When I do a cls2 = cls1, > and I change a property of cls2, this property is also changed in my > cls1!! You don't have two instances, you only have one.
Your instance is created in this line:
\\\ Dim cls1 As New clsMyClass ///
The following line does not create another instance, it simply points cls2 at the existing instance that cls1 is already referencing:
\\\ cls2 = cls1 ///
After this, both cls1 and cls2 are pointing to the same object instance, hence the behaviour you described.
To prevent it, create two object instances:
\\\ Dim cls1 As New clsMyClass Dim cls2 As New clsMyClass ///
 Signature (O)enone
S. Senthil Kumar - 10 Aug 2005 17:11 GMT That's because cls1 and cls2 are *references* to objects and not the actual objects themselves. Assigning cls2 to cls1 simply makes them both refer to the same object and that's why changing a property affects both.
I suggest you implement the ICloneable interface in your user defined class and do something like cls2 = (MyClass)cls1.Clone();
Regards Senthil
DraguVaso - 10 Aug 2005 17:25 GMT Well, I tried that, but I have a Brush-property in my Class, and that gives me this exception...
The type System.Drawing.Brush in Assembly System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is not marked as serializable. at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMember s(RuntimeType type, Boolean excludeNonSerializable) at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) etc etc etc...
Any idea to get around this problem?
> That's because cls1 and cls2 are *references* to objects and not the > actual objects themselves. Assigning cls2 to cls1 simply makes them [quoted text clipped - 7 lines] > Regards > Senthil S. Senthil Kumar - 10 Aug 2005 17:55 GMT >From the exception, it looks like you tried serializing and deserializing your class to get a copy. System.Drawing.Brush is not serializable and that's why you are getting the exception.
Do you need to deep copy everything?
Regards Senthil
DraguVaso - 11 Aug 2005 08:15 GMT Yes unfortunately yes :) It's actually a deep copy that I need to make. I guess ThunderMusic's method will be the best now...
> >From the exception, it looks like you tried serializing and > deserializing your class to get a copy. System.Drawing.Brush is not [quoted text clipped - 4 lines] > Regards > Senthil Cor Ligthert [MVP] - 10 Aug 2005 19:47 GMT Pieter,
Any reason why you don't do what Oenone suggest you?
Cor
DraguVaso - 11 Aug 2005 08:18 GMT Because it doesn't work... Dim cls1 As New clsMyClass Dim cls2 As New clsMyClass cls2 = cls1 '-> This still creates a reference to my cls1, so changes I make to cls2 will be changed automaticly to cls1 also...
> Pieter, > > Any reason why you don't do what Oenone suggest you? > > Cor Cor Ligthert [MVP] - 11 Aug 2005 09:10 GMT Pieter,
You are always talking about classes
Dim cls1 as New clsMyClass Dim cls2 as New clsMyClass is in fact Dim obj1 as new clsMyClass dim obj2 as new clsMyClass
Gives 2 completly independedn objects
dim obj1 = obj2
Sets the reference from obj2 to obj1, so the point to the same object
In the same time the first instanced obj2 has no reference anymore and therefore that obj2 will be garbaged by the GC.
I hope this gives an idea,
Cor
Oenone - 11 Aug 2005 11:45 GMT > Because it doesn't work... > Dim cls1 As New clsMyClass > Dim cls2 As New clsMyClass > cls2 = cls1 '-> This still creates a reference to my cls1, > so changes I make to cls2 will be changed automaticly to cls1 also... I think I'm struggling to work out what you're actually trying to do.
You asked a question about why after running the above code changes made to cls2 also affect cls1, and we've answered that question.
What exactly is the problem you are trying to solve? Are you trying to create two separate objects and copy all of the property values from one object to the other?
 Signature (O)enone
DraguVaso - 11 Aug 2005 12:52 GMT Yes indeed! That's exactly what I want! I want my cls2 to be exactly the same as my cls1, but when I change a value in cls2, it shouldn't affect cls1. What I need is a Deep Copy...
I now made a Constructor of my clsMyclass that gets a clsMyClass argument, and copies all it's properties one by one in its own properties. It isn't really beautiful, but it works... My class has only 10 property's so it's not too hard, but when having classes with much more properties a nicer solution should be welcome, hehe :)
Thanks anyway for the explanation and the help.
Pieter
> > Because it doesn't work... > > Dim cls1 As New clsMyClass [quoted text clipped - 10 lines] > create two separate objects and copy all of the property values from one > object to the other? Cor Ligthert [MVP] - 11 Aug 2005 14:18 GMT Pieter,
If you want a deepcopy of an object than the most simple method to make the class from which its instanced serializable and than to serialise it and create using deserialization a copy of that object.
I hope this helps,
Cor
DraguVaso - 12 Aug 2005 08:21 GMT Yes I tried that, but unfortunately I got an error (as I mentioned alreaddy somewhere in another post): It seems that a Brush-object in't serializable...
The type System.Drawing.Brush in Assembly System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is not marked as serializable. at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMember s(RuntimeType type, Boolean excludeNonSerializable) at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) etc etc etc...
> Pieter, > [quoted text clipped - 5 lines] > > Cor DraguVaso - 11 Aug 2005 09:11 GMT I found a solution somewhere that works. It's using Reflection, and I implemented in a New() just like ThunderMusic suggested. It works great! Thanks a lot for the suggestions!
Imports System.Reflection
Public Sub New(ByVal clsSource As clsMyClass) MyBase.New()
Dim pi As PropertyInfo() = GetType(clsMyClass).GetProperties Dim objValue As Object
For intX As Integer = 0 To pi.Length - 1 With pi(intX) 'If .GetIndexParameters().Length = 0 Then 'Copy objValue = .GetValue(clsSource, Nothing) 'Paste .SetValue(Me, objValue, Nothing) 'Else ' Debug.WriteLine(.Name & " " & "<array>") 'End If End With Next intX End Sub
> Hi, > [quoted text clipped - 36 lines] > > End Class DraguVaso - 11 Aug 2005 09:24 GMT Oh no, forget about my solution: It's totally worthless. ok, it works, but it eats resources like hell!! It's slowing down everything, and it's too much remarkable... :-(
> I found a solution somewhere that works. It's using Reflection, and I > implemented in a New() just like ThunderMusic suggested. It works great! [quoted text clipped - 63 lines] > > > > End Class S. Senthil Kumar - 11 Aug 2005 17:40 GMT Your solution doesn't seem to do a deep copy either. You get the property values using reflection and just assign them to the new object, so reference type member variables will still be shared.
Regards Senthil
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|