Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / August 2005

Tip: Looking for answers? Try searching our database.

MyClass2 = MyClass1 -> ByRef????

Thread view: 
Enable EMail Alerts  Start New Thread
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

Rate this thread:







Free Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.