Accessing shared class members via an instance and why this is not a good idea.
Accessing shared class members via an instance and why this is not a good idea.
Let’s consider this code:
Module Module1
Sub Main()
Dim x As New C1
Dim z As Integer
z = x.SharedVariable
Console.WriteLine(z)
End Sub
End Module
Class C1
Public Shared SharedVariable As Integer = 1
End Class
“There is nothing wrong” you would say. We get x.SharedVariable and print it out. But this is not entirely correct. The tricky part is the way we are using x here.
Strictly speaking shared members do not belong to a particular instance. They are part of the type itself and belong to the type that defines them. Unlike instance fields that have a separate copy for each instance, the shared field has only one copy and it is attached to the class itself.
It would be more expressive if we get the SharedVariable from C1 directly:
C1.SharedVariable
In fact internally compiler does exactly that. It replaces x with its type and x.SharedVariable becomes C1.SharedVariable
Now let’s check this code:
Module Module1
Sub Main()
Dim x As New C1
Dim y As New C2
Dim z As Integer = y.WriteHelloGetC1Inst.SharedVariable
Console.WriteLine(z)
End Sub
End Module
Class C1
Public Shared SharedVariable As Integer = 1
End Class
Class C2
Public Function WriteHelloGetC1Inst() As C1
Console.WriteLine("hello")
Return New C1
End Function
End Class
Would you expect to see “hello” on the console when you get y.WriteHelloGetC1.SharedVariable?
Rriiiight. You will not. Compiler will replace whole y.WriteHelloGetC1Inst with C1 and you will get this instead:
C1.SharedVariable
Pretty sneaky. Actually anything like <huge_expression_returning_C1_instance>.SharedVariable will be understood by the compiler as just C1.SharedVariable without going through trouble of evaluating <huge_expression_returning_C1_instance>.
It seems that it would be much better if you write just C1.SharedVariable to not make an impression that something else is called.
Actually in the next version of VB.Net compiler politely warns you against using misleading syntax:
Module1.vb(6) : warning BC42025: Access of shared member through instance variable. Preceding expression will not be evaluated.