I wrote a code to demonstrate the issue:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
doSomething()
End Sub
Dim controlArr() As Object = {NumericUpDown1, NumericUpDown2, NumericUpDown3, NumericUpDown4, CheckBox1, CheckBox2, CheckBox3, CheckBox4}
Private Sub doSomething()
Dim testStr As String = ""
For Each control In controlArr
Select Case control.GetType
Case GetType(NumericUpDown)
control.value = 1
Case GetType(CheckBox)
control.checked = True
End Select
Next
End Sub
End Class
When I run the code I receive Null Referenece Exception "Object reference not set to an instance of an object", the error disapears when I declare the controlArr
array inside DoSomething
subroutine. Anyway I would prefer having it declared outside since I am using it in many functions. I would like to understand it better so if you provided me with a topic I could read up on I would be very grateful. Thank you very much for your help.
The issue is that declarations are processed before the constructor. That means that this line:
Dim controlArr() As Object = {NumericUpDown1, NumericUpDown2, NumericUpDown3, NumericUpDown4, CheckBox1, CheckBox2, CheckBox3, CheckBox4}
is executed before the code that creates all the controls on the form and assigns them to those fields. As such, all the fields are Nothing
at the time that code is executed and so your array contains a whole lotta nothin'. There's no issue creating objects to initialise fields like that and that code does successfully create an array. It's just that you are implicitly setting every element of that array to Nothing
so that's what you get to use later on.
If you want to reference any control then you have to wait until after the form's controls are created. That means, at the earliest, after the call to InitializeComponent
in the constructor. More generally, you should do it in the Load
event handler, e.g.
Dim controlArr As Object()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Form1.Load
controlArr = {NumericUpDown1, NumericUpDown2, NumericUpDown3, NumericUpDown4, CheckBox1, CheckBox2, CheckBox3, CheckBox4}
End Sub