Raymond Lewallen

A few things .Net, a few things Sql

<November 2008>
SuMoTuWeThFrSa
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456


Navigation

General

Subscriptions

Post Categories



Tuesday, December 07, 2004 - Posts

Fields and constants for VB Beginners
Here's a simple VB test anybody who programs in .Net should understand, yet you might be suprised at the number of people who don't understand how values and references work (explained here), and also don't understand how fields and constants work. I decided to put this up when a friend emailed me asking why something wouldn't work the way he was expecting.

Note: This test does not apply to C#, and actually can't be converted to C# as is, and I'll explain why later, along with the C# equivalent of the test.

Public Class Test

Private A As Int32 = 5
Const B As Int32 = 20
Private ReadOnly C As Int32 = 10

Public Sub New()
Go()
End Sub

Private Sub Go()
Console.WriteLine(Bar(A))
Console.WriteLine(Bar(B))
Console.WriteLine(Bar(C))

Foo(A)
Foo(B)
Foo(C)

Console.WriteLine(A)
Console.WriteLine(B)
Console.WriteLine(C)
Console.WriteLine(Bar(A))
Console.WriteLine(Bar(B))
Console.WriteLine(Bar(C))
End Sub

Private Sub Foo(ByRef x As Int32)
x = x + 5
End Sub

Private Function Bar(ByVal x As Int32) As Int32
Return x + 5
End Function

End Class

The output would look like the following:
10
25
15
10
20
10
15
25
15

Console.WriteLine(Bar(A)) outputs 10
Console.WriteLine(Bar(B)) outputs 25
Console.WriteLine(Bar(C)) outputs 15
Then we call Foo() with each of the fields and the constant.
Console.WriteLine(A) outputs 10
Console.WriteLine(B) outputs 20
Console.WriteLine(C) outputs 10
Console.WriteLine(Bar(A)) outputs 15
Console.WriteLine(Bar(B)) outputs 25
Console.WriteLine(Bar(C)) outputs 15

So, the only thing here that I see beginners not understanding is what goes one when calling Foo() and what gets output in the following 3 lines following Foo() calls. When calling Foo(), each one of A, B and C is still the value that they were at the time they were initialized. Bar() doesn't change any of the values, because Bar() takes its parameters by value, which does a copy of the fields in memory, thus preserving the values of the passed types. The tricky part is the calls to Foo(). Foo() takes its parameters by reference, which really just passes the address of the type being passed, and not a copy of the type. This means any change to value of the passed parameter will change the value of the initial type itself. So, that explains why A was 10 after the call to Foo(), but hey, shouldn't B and C have been 25 and 15, respectivly? Ah, there's the trick that most beginners miss. B is a constant, and cannot have its value changed after initialization (there are exceptions to this in VB, but we'll save that for another time). C is a ReadOnly field. The definition of a ReadOnly field specifies that its value can only be changed from the instance constructor or the type constructor, so Foo() cannot change its value either. The only value we can change when accessing the types memory address, thus the type itself, is A, our private read/write field.

I'll explain the differences in this code in C#, and why it doesn't work the same way, but I'm going to have to save that for later.

posted Tuesday, December 07, 2004 6:00 AM by rlewallen




Powered by Dot Net Junkies, by Telligent Systems