To answer your first question (the use of the = operator):
Of course, X will not = 20. You need to understand how assignment works with value types and reference types--the behavior of = is, in fact, already explicitly defined. If you look at it from the right prespective, they actually work the same way.
First, examine the way that normal (value-type) variable assignment works. When you say
SomeVariable = SomeValue, you have a spot in memory referenced by
SomeVariable and the value,
SomeValue, is copied into that spot in memory. Let's look at a play-by-play:
Visual Basic:
'--------------------------X----Y
dim x as integer = 5 ' [U]5[/U] 0 The value of 5 is copied to x
dim y as integer = 10 ' 5 [U]10[/U] The value of 10 is copied to y
x = y ' [U]10[/U] 10 The value of Y (10) is copied to x
y = 20 ' 10 [U]20[/U] The value is 20 is copied to Y (but not to X)
Now we look at reference types. If you have any experience at all with C# or ASM, you will be familiar with pointers. A pointer is just a 32-bit integer (in Win32) that references a memory location. Pointers are at the heart of .Net reference types. A variable that is declared as a reference type actually only stores a pointer. When you call a method or set a field or property, you tell the compiler "Perform this operation on the object stored at the memory location specified by my variable." For example, the code
MyObject.SomeFunction() compiles down to "Call
SomeFunction on the object that the pointer in
MyObject points to."
The signifigance of that is that you must understand that reference-type variables are just pointers, internally represented exactly like an integer. So, when you assign an object to a variable, the reference (i.e. the pointer) is being assigned. Let's have a look.
Visual Basic:
'Class that holds a single value
Class SampleClass
Public Value As Integer
'Create instance with specified value
Public Sub New(val As Integer)
Value = val
End Sub
End Class
'Now, let's examine how assignment works here.
'These memory locations are random, picked out of a hat, just to demonstrate.
Sub ShowAssignment()
'MemoryLocation----------------X----------------Y---------------------
'Value-----------------------------------X--------------Y-------------
Dim X As New SampleClass(5) '[U]123456[/U] [U]5[/U] 0 (Nothing)
Dim Y As New SampleClass(10) '123456 5 [U]90210[/U] [U]10[/U]
X.Value = Y.Value '123456 [U]10[/U] 90210 10
Y.Value = 20 '123456 10 90210 [U]20[/U]
' So far the values seem to be exactly the same as before.
' Here's where things get different:
' We will assign the pointer of Y to X
X = Y '[U]90210 20[/U] 90210 20
' X now points to a different location in memory than before: the
' same location as Y. Now a change in Y will be reflected in X, and
' vice-versa
X.Value = 100 '90210 [U]100[/U] 90210 [U]100[/U]
' Notice that because X and Y point to the same memory, their value
' WILL ALWAYS be the same.
End Sub
The confusion comes from the fact that .Net does a real good job of hiding your pointers from you. If you get a good grasp on how pointers work, though, you will have a good understanding of how and why reference types behave the way they do.
To answer your question about making an exact copy of a button: This is not nearly as simple as it seems. If you create a member-by-member clone ("shallow copy") of a button you will run into problems, and fast. Button objects are full of pointers. If you create a member-by-member clone of a .Net Button object you will copy all the
pointers instead of the data that the pointers reference (copying all the data that the pointers point to would be a "deep copy"). This means that you will have two objects that .Net thinks are separate buttons, but they will both reference the same Windows resources (i.e.
Windows will think that they are the same button while .Net thinks they are different).
If you assign one Button variable to another it will just copy .Net's pointer, so both .Net and Windows will treat it as the same object.
If you want to create a duplicate of a Button you will have to write your own function to do so. It will have to create a new button and then copy all of the properties over.