-----------------------------------------------------------

New Message on BDOTNET

-----------------------------------------------------------
From: Sitaraman
Message 1 in Discussion

 Hi Group  In general when u want a variable to be shared at class level, you use a 
static(Shared in VB.Net) variable. The words "Shared and "Static" are quite confusing 
. "In VB.Net(not in C#) , you have the Shared and the Static keywords. It means that 
it is possible to have  a) Class Level(Member) Static variable -Using the Shared 
Keyword  b) Method Level(Local) Static variable(???) -Using the Static Keyword(not in 
C#)  Some of the articles talk about both Shared and Static being the same only that 
their scope being different. But this is not quite accurate. When u declare a local 
variable as Static, the behaviour is quite interesting.          If the Function in 
which the static variable is declared is itself NOT Shared, then the local static 
variables will behave like simple Class Level Instance variables, that is they will 
retain the data till the time the object goes out of scope and the data is not shared 
across instances         If the Function in which the static variable is declared is 
itself Shared, then the local static variables will behave like Class Level Shared 
Variables and the data is shared across instances. Al this might sound confusing. So 
lets take a look at the example below    
----------------------------------------------------------------------------------------------------------------------------------------------------------
 Module Module1
Sub Main()  Console.WriteLine("C L M S V V - Class Level Member Shared Variable 
Value") Console.WriteLine("C L M I V V - Class Level Member Instance Variable Value") 
Console.WriteLine("MLLSVV - Method Level Local Shared Variable Value")x()
y()
Console.ReadLine()
Console.WriteLine("Calling x() and y() again.Note the difference. Press Enter to See 
the next set of Output" & vbCrLf)
x()
y() Console.WriteLine("Press Enter to Exit" & vbCrLf)
Console.ReadLine()
End Sub
Sub x()
Dim l_objTestClass As New TestClass()
Dim ictr As Integer Console.WriteLine("Instance 1 INSTANCE 
Method(fnPrintSharedAndStaticVariableValues) Call output")
Console.WriteLine("----------------------------------------")
For ictr = 0 To 5
l_objTestClass.fnPrintSharedAndStaticVariableValues()
Next
Console.WriteLine("----------------------------------------" & vbCrLf)
Console.WriteLine("Press Enter to See the next set of Output" & vbCrLf)
Console.ReadLine() Dim l_objTestClass2 As New TestClass() 
Console.WriteLine("Instance 2 INSTANCE Method(fnPrintSharedAndStaticVariableValues) 
Call output")
Console.WriteLine("NOTE THAT THE CLASS LEVEL VARIABLE RETAINS VALUE AND NOT THE OTHER 
TWO(CLASS LEVEL INSTANCE VARIABLE AND NORMAL METHOD LEVEL STATIC VARIABLE) ")
Console.WriteLine("----------------------------------------")
For ictr = 0 To 5
l_objTestClass2.fnPrintSharedAndStaticVariableValues()
Next
Console.WriteLine("----------------------------------------" & vbCrLf)
Console.WriteLine("Press Enter to See the next set of Output" & vbCrLf)
Console.ReadLine()
End Sub Sub y()
Dim l_objTestClass As New TestClass()
Dim ictr As Integer Console.WriteLine("Instance 1 SHARED 
Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output")
Console.WriteLine("----------------------------------------")
For ictr = 0 To 5
l_objTestClass.fnSHAREDPrintSharedAndStaticVariableValues2()
Next
Console.WriteLine("----------------------------------------" & vbCrLf)
Console.WriteLine("Press Enter to See the next set of Output" & vbCrLf)
Console.ReadLine() Dim l_objTestClass2 As New TestClass() 
Console.WriteLine("Instance 2 SHARED 
Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output")
Console.WriteLine("NOTE THAT BOTH THE CLASS LEVEL VARIABLE AND SHARED NORMAL LEVEL 
STATIC VARIABLE RETAIN VALUE ) ")
Console.WriteLine("----------------------------------------")
For ictr = 0 To 5
l_objTestClass2.fnSHAREDPrintSharedAndStaticVariableValues2()
Next
Console.WriteLine("----------------------------------------" & vbCrLf) 
End Sub
End Module

 Public Class TestClass   'Declare a Class Level(Member) Shared Variable
Shared m_intSharedVariable1 As Integer = 0 'Declare a Class Level Member Instance 
Variable
Private m_intVariable1 As Integer = 0    Public Function 
fnPrintSharedAndStaticVariableValues() 
'Declare a Method Level(Local) Static Variable
Static l_intStaticVariable1 As Integer = 0    'Increment the Class Level(Member) 
Shared Variable
m_intSharedVariable1 = m_intSharedVariable1 + 1 'Increment the Class Level Member 
Instance Variable
m_intVariable1 = m_intVariable1 + 1 'Increment the Method Level(Local) Static Variable
l_intStaticVariable1 = l_intStaticVariable1 + 1    'Print the value of the Class 
Level(Member) Shared Variable
Console.WriteLine("C L M S V V: " & m_intSharedVariable1) 'Print the value of the 
Class Level(Member) Instance Variable
Console.WriteLine("C L M I V V: " & m_intVariable1)
'Print the value of the Method Level(Local) Static Variable
Console.WriteLine("M L L S V V : " & l_intStaticVariable1) 
End Function 
 
Public Shared Function fnSHAREDPrintSharedAndStaticVariableValues2() 

'Declare a Method Level(Local) Static Variable
Static l_intStaticVariable1 As Integer = 0  'Increment the Class Level(Member) Shared 
Variable
m_intSharedVariable1 = m_intSharedVariable1 + 1 'Increment the Method Level(Local) 
Static Variable
l_intStaticVariable1 = l_intStaticVariable1 + 1    'Print the value of the Class 
Level(Member) Shared Variable
Console.WriteLine("C L M S V V: " & m_intSharedVariable1) 'Print the value of the 
Method Level(Local) Static Variable
Console.WriteLine("M L L S V V : " & l_intStaticVariable1)
End Function
 
End Class
----------------------------------------------------------------------------------------------------------------------------------------------------------
 The output of this would be  ----------------------------------------  C L M S V V - 
Class Level Member Shared Variable Value C L M I V V - Class Level Member Instance 
Variable Value MLLSVV - Method Level Local Shared Variable Value Instance 1 INSTANCE 
Method(fnPrintSharedAndStaticVariableValues) Call output
----------------------------------------
C L M S V V : 1
C L M I V V: 1
M L L S V V : 1
C L M S V V : 2
C L M I V V : 2
M L L S V V : 2
C L M S V V : 3
C L M I V V : 3
M L L S V V : 3
C L M S V V : 4
C L M I V V : 4
M L L S V V : 4
C L M S V V : 5
C L M I V V : 5
M L L S V V : 5
C L M S V V : 6
C L M I V V : 6
M L L S V V : 6
---------------------------------------- Press Enter to See the next set of Output 
Instance 2 INSTANCE Method(fnPrintSharedAndStaticVariableValues) Call output
NOTE THAT THE CLASS LEVEL VARIABLE RETAINS VALUE AND NOT THE OTHER TWO(CLASS LEVEL 
INSTANCE VARIABLE AND NORMAL METHOD LEVEL STA
TIC VARIABLE)
----------------------------------------
C L M S V V : 7
C L M I V V : 1
M L L S V V : 1
C L M S V V : 8
C L M I V V : 2
M L L S V V : 2
C L M S V V : 9
C L M I V V : 3
M L L S V V : 3
C L M S V V : 10
C L M I V V : 4
M L L S V V : 4
C L M S V V : 11
C L M I V V: 5
M L L S V V : 5
C L M S V V : 12
C L M I V V : 6
M L L S V V : 6
---------------------------------------- Press Enter to See the next set of Output 
Instance 1 SHARED Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output
----------------------------------------
C L M S V V : 13
M L L S V V : 1
C L M S V V : 14
M L L S V V : 2
C L M S V V : 15
M L L S V V : 3
C L M S V V : 16
M L L S V V : 4
C L M S V V : 17
M L L S V V : 5
C L M S V V : 18
M L L S V V : 6
---------------------------------------- Press Enter to See the next set of Output 
Instance 2 SHARED Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output
NOTE THAT BOTH THE CLASS LEVEL VARIABLE AND SHARED NORMAL LEVEL STATIC VARIABLE RETAIN 
VALUE )
----------------------------------------
C L M S V V : 19
M L L S V V : 7
C L M S V V : 20
M L L S V V : 8
C L M S V V : 21
M L L S V V : 9
C L M S V V : 22
M L L S V V : 10
C L M S V V : 23
M L L S V V : 11
C L M S V V : 24
M L L S V V : 12
---------------------------------------- 
Calling x() and y() again.Note the difference. Press Enter to See the next set of 
Output Instance 1 INSTANCE Method(fnPrintSharedAndStaticVariableValues) Call output
----------------------------------------
C L M S V V : 25
C L M I V V : 1
M L L S V V : 1
C L M S V V : 26
C L M I V V: 2
M L L S V V : 2
C L M S V V : 27
C L M I V V: 3
M L L S V V : 3
C L M S V V : 28
C L M I V V: 4
M L L S V V : 4
C L M S V V : 29
C L M I V V: 5
M L L S V V : 5
C L M S V V : 30
C L M I V V: 6
M L L S V V : 6
---------------------------------------- Press Enter to See the next set of Output 
Instance 2 INSTANCE Method(fnPrintSharedAndStaticVariableValues) Call output
NOTE THAT THE CLASS LEVEL VARIABLE RETAINS VALUE AND NOT THE OTHER TWO(CLASS LEVEL 
INSTANCE VARIABLE AND NORMAL METHOD LEVEL STA
TIC VARIABLE)
----------------------------------------
C L M S V V : 31
C L M I V V : 1
M L L S V V : 1
C L M S V V : 32
C L M I V V: 2
M L L S V V : 2
C L M S V V : 33
C L M I V V: 3
M L L S V V : 3
C L M S V V : 34
C L M I V V: 4
M L L S V V : 4
C L M S V V : 35
C L M I V V: 5
M L L S V V : 5
C L M S V V : 36
C L M I V V: 6
M L L S V V : 6
---------------------------------------- Press Enter to See the next set of Output 
Instance 1 SHARED Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output
----------------------------------------
C L M S V V : 37
M L L S V V : 13
C L M S V V : 38
M L L S V V : 14
C L M S V V : 39
M L L S V V : 15
C L M S V V : 40
M L L S V V : 16
C L M S V V : 41
M L L S V V : 17
C L M S V V : 42
M L L S V V : 18
---------------------------------------- Press Enter to See the next set of Output 
Instance 2 SHARED Method(fnSHAREDPrintSharedAndStaticVariableValues2) Call output
NOTE THAT BOTH THE CLASS LEVEL VARIABLE AND SHARED NORMAL LEVEL STATIC VARIABLE RETAIN 
VALUE )
----------------------------------------
C L M S V V : 43
M L L S V V : 19
C L M S V V : 44
M L L S V V : 20
C L M S V V : 45
M L L S V V : 21
C L M S V V : 46
M L L S V V : 22
C L M S V V : 47
M L L S V V : 23
C L M S V V : 48
M L L S V V : 24
---------------------------------------- Press Enter to Exit 
----------------------------------------    The output shows that the Method 
Level(Local) Static Variables behave differently when declared in a instance method 
and a Shared method.           The Method level Static Variable l_intStaticVariable1 
behaves just like the Class Level Instance Variable m_intVariable1, because it is 
defined in a instance method fnPrintSharedAndStaticVariableValues.      The Method 
level Static Variable l_intStaticVariable2 behaves just like the Class Level Shared 
Variable m_m_intSharedVariable1, because it is defined in a Shared method 
fnSHAREDPrintSharedAndStaticVariableValues2 How is this possible. How exactly are 
Method Level Static Variables handled. Are they instance based or static. How is the 
data persisted even though they are declared inside a method.   There is no magic in 
it and an answer all this is the is the juggling that the vbc compiler performs to 
achieve this dynamism at the time of compiling the Source Code to IL   Lets see how it 
actually happened in 2 steps below   1) IL Level : The Source Code is compiled to IL. 
Right!!! Lets use the ILDASM on the compiled code to see how the Disassembly looks 
like  Test Class        
$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1:private 
specialname int32       
$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init : private 
specialname class        
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$2001C$l_intStaticVariable2:private 
static specialname int32         
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$2001C$l_intStaticVariable2$Init : 
private static specialname class 
[Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag      
  m_intSharedVariable1 : private static int32     method public instance object 
fnPrintSharedAndStaticVariableValues() cil managed        method public static object 
fnSHAREDPrintSharedAndStaticVariableValues2() cil managed If u look at the TestClass 
Source Code we had one variable m_intSharedVariable1, which was Shared and one 
function fnPrintSharedAndStaticVariableValues. However on compilation the VB Compiler 
has done some extra tasks for free. it has         made the Shared Keyword as 
static(which is cool and is consistent with C# semantics also and is irrelevant for us 
now)
         Moved(Copied to be precise) the Method Level(Local) Variable 
l_intStaticVariable1 to a Class Level Member(instance) variable and assigned it a 
unique variable name, 
$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1.Note that it 
is a combination of the the Name of the "Method Level Static Variable" + The Name of 
the Method in which this variable was declared + Special Characters.Also note that the 
newly created Class Level variable is an instance variable coz, the function in which 
the static variable was defined was an instance 
method(fnPrintSharedAndStaticVariableValues)
         Added one more Variable 
$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init of type 
Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag (This is a interesting 
namespace, has a wonderful set of utility functions, more on it later). This is an 
instance variable for the reason as mentioned in point 2
         Moved(Copied to be precise) the Method Level(Local) Variable 
l_intStaticVariable2 to a Class Level Member(static) variable and assigned it a unique 
variable name, 
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$2001C$l_intStaticVariable2.Note 
that it is a combination of the the Name of the "Method Level Static Variable" + The 
Name of the Method in which this variable was declared + Special Characters. Also note 
that the newly created Class Level variable is an static variable coz, the function in 
which the static variable was defined was a Shared 
method(fnSHAREDPrintSharedAndStaticVariableValues2)
         Added one more Variable 
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$2001C$l_intStaticVariable2$Init of 
type Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag . This is Shared 
variable for the reason as mentioned in point 4  
So from this wat we can guess is that, when u create a local static variable, on 
compilation the compiler creates a class level instance variable and also creates a 
flag. So whenever this variable is accessed for the first time, the variable will be 
initialized with the value and after tht it will always hold the value across method 
calls just as any static variable. But how to be sure that we are correct. Ill use the 
Reflector tool( the download link for which i had posted some time ago) to DECOMPILE 
the exe and look at the function 2) DeCompiled Code Level : When you decompile the 
code using the Reflector tool( u can download it from 
http://www.aisto.com/roeder/dotnet/, SDK also available), the decompiled source code 
is as follows     Public Class TestClass Inherits Object   Private 
$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1 As Integer
Private $STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init 
As StaticLocalInitFlag
Private Shared 
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2 As 
Integer
Private Shared 
$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init As 
StaticLocalInitFlag
Private Shared m_intSharedVariable1 As Integer
Private m_intVariable1 As Integer  Private Shared Sub New()
Begin Sub
TestClass.m_intSharedVariable1 = 0
TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init
 = New StaticLocalInitFlag
End Sub  Public Sub New()
Begin Sub
MyBase..ctor
Me.m_intVariable1 = 0
Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init = New 
StaticLocalInitFlag
End Sub  Public Function fnPrintSharedAndStaticVariableValues() As Object
Begin Function
Dim obj1 As Object
If 
(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init.State 
= 1) Then
goto L_0071

End If
Monitor.Enter(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init)
If 
(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init.State 
= 0) Then
Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init.State 
= 2
Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1 = 0

Else
If 
(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init.State 
= 2) Then
Throw New IncompleteInitialization

End If

End If
goto L_0070
Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init.State 
= 1
Monitor.Exit(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1$Init)

L_0070:
TestClass.m_intSharedVariable1 = (TestClass.m_intSharedVariable1 + 1)
Me.m_intVariable1 = (Me.m_intVariable1 + 1)
Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1 = 
(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1 + 1)
Console.WriteLine(String.Concat("C L M S V V : ", 
StringType.FromInteger(TestClass.m_intSharedVariable1)))
Console.WriteLine(String.Concat("Class Level(Member) Variable Value : ", 
StringType.FromInteger(Me.m_intVariable1)))
Console.WriteLine(String.Concat("M L L S V V : ", 
StringType.FromInteger(Me.$STATIC$fnPrintSharedAndStaticVariableValues$2001C$l_intStaticVariable1)))
Return obj1 
End Function  
Public Shared Function fnSHAREDPrintSharedAndStaticVariableValues2() As Object
Begin Function
Dim obj1 As Object
If 
(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init.State
 = 1) Then
goto L_0069

End If
Monitor.Enter(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init)
If 
(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init.State
 = 0) Then
TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init.State
 = 2
TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2
 = 0

Else
If 
(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init.State
 = 2) Then
Throw New IncompleteInitialization

End If

End If
goto L_0068
TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init.State
 = 1
Monitor.Exit(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2$Init)

L_0068:
TestClass.m_intSharedVariable1 = (TestClass.m_intSharedVariable1 + 1)
TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2
 = 
(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2
 + 1)
Console.WriteLine(String.Concat("C L M S V V : ", 
StringType.FromInteger(TestClass.m_intSharedVariable1)))
Console.WriteLine(String.Concat("M L L S V V : ", 
StringType.FromInteger(TestClass.$STATIC$fnSHAREDPrintSharedAndStaticVariableValues2$001C$l_intStaticVariable2)))
Return obj1 
End Function  
End Class      Here note that both the functions are almost the same. Basically wat 
the compiler has done is to add some plumbing code(Adding Class Level Variable Flag 
Checking, Initialization of Flag etc) and modify existing code(the local variable that 
u declared has been removed by the compiler and some inlining has been done) to ensure 
that the Method level Static Variable is managed  To Conclude     A Static(Method 
Level) Variable is does not automatically translate to a Shared(Class Level) Variable  
 Only similarity is that it is capable of retaining the data even after the method 
call is over, which is possible even in an instance variable          A Method Level 
Static Variable Declared in a method can become either a Class Level Instance Variable 
or a Class Level Shared Variable          If the variable's declaring method is a 
Shared method then the compiler will create an equivalent Class Level Shared Variable 
for the Method Level Static Variable      If the variable's declaring method is a 
Instance method then the compiler will create an equivalent Class Level Instance 
Variable for the Method Level Static Variable          All the juggling and plumbing 
code is written by the compiler to check for initialization etc. 
Hope this helps 
Im attaching the sample solution of the example given above. The ILDASM tool can be 
loaded from the VS.Net Command Prompt by typing ILDASM.exe <EXE/DLL FileName>. The 
Reflector tool can be downloaded from http://www.aisto.com/roeder/dotnet/ . 
Hope this helps 
regards,  sr  p.s. The MSDN does not provide much help on the CompilerServices 
Namespace. Even intellisense does not show me the classes. So i opened the 
Microsoft.VisualBasic 
Assembly(file:///c:/winnt/assembly/gac/microsoft.visualbasic/7.0.3300.0__b03f5f7f11d50a3a/microsoft.visualbasic.dll
 on my machine which runs .Net1.0 FW ) in the Reflector tool and checked the 
CompilerServices Namespace classes. There are quite a few useful methods available 
here which will help u understand how exactly are things manipulated at compiletime. 
Check it out.....

-----------------------------------------------------------

To stop getting this e-mail, or change how often it arrives, go to your E-mail 
Settings.
http://groups.msn.com/BDotNet/_emailsettings.msnw

Need help? If you've forgotten your password, please go to Passport Member Services.
http://groups.msn.com/_passportredir.msnw?ppmprop=help

For other questions or feedback, go to our Contact Us page.
http://groups.msn.com/contact

If you do not want to receive future e-mail from this MSN group, or if you received 
this message by mistake, please click the "Remove" link below. On the pre-addressed 
e-mail message that opens, simply click "Send". Your e-mail address will be deleted 
from this group's mailing list.
mailto:[EMAIL PROTECTED]

Reply via email to