Visual basic variable is used before it has assigned value - vb.net

this code is the same as others it is a random between 1 and 4 yet for some reason it says it is being used before it has a value it is the same code as 3 others that are the same but with different names yet this is happening can someone please help me?
Dim npc As Random
Dim ndamage As Integer
ndamage = npc.Next(1, 4)
If (Playerhealth.Value - ndamage) <= 0 Then
Playerhealth.Value = 0
Else
Playerhealth.Value = Playerhealth.Value - ndamage
End If

In the first three lines of code,
Dim npc As Random
Dim ndamage As Integer
ndamage = npc.Next(1, 4)
you declare npc and use it before it is assigned a value. You should use New to create a new instance:
Dim npc As New Random
Further Explanation
Random is a class, which means that its default value is Nothing (also called null in C#), so before it can be used it needs to be assigned a value. The easiest way in this case is to use New directly in the variable declaration line.

Random is a Class which provides a lot of methods to get different random numbers.
To access these methods you have to create an object (sometimes called instance) of that class.
This is done by the new operator. This operator will allocate new space on the heap (which is a memory area) and will fill it with objects values and references to methods and other objects.
If you skip the new statement, you program tries to access to not allocated memory. In several languages this will end up in an nullpointer exception, in vb.net you get an used before it has assigned value exception.
To solve your problem, create an object of the random class:
Dim npc As New Random

Related

Random from listbox

there has been many posts about this but nobody seems to have my problem.
I have a list box with letters a-z (line for each letter)
using
Dim rancon As New Random
Dim rc As Integer = ListBox1.Items.Count
Label5.Text = lcon.Items.Item(rancon.Next(rc)).ToString
all it is doing is chosing randomly, 1 of the first 7 or 8 characters.
can anyone advise?
I assume that you expect that the random always chooses a different item in the ListBox. Therefore you have to reuse the same Random instance since the default constructor derives the seed(which is used to initialize the pseudorandom number generator) from the current system time.
If you call this code very fast(for example in a loop), the seed will always be the same. Hence you get repeating numbers/items.
To avoid this you could make the Random a field in the class:
Private rancon As New Random
Public Sub YourMethod()
Dim rc As Integer = ListBox1.Items.Count
Label5.Text = ListBox1.Items(rancon.Next(rc)).ToString()
End Sub
MSDN:
The default seed value is derived from the system clock and has finite
resolution. As a result, different Random objects that are created in
close succession by a call to the default constructor will have
identical default seed values and, therefore, will produce identical
sets of random numbers. This problem can be avoided by using a single
Random object to generate all random numbers. You can also work around
it by modifying the seed value returned by the system clock and then
explicitly providing this new seed value to the Random(Int32)
constructor.
Note that i've also used ListBox1.Items instead of lcon.Items in case that was a typo.

Why is new not used when a DataTable object is created?

I understand that everything in vb.net is a object. If that is the case, why is new keyword not used when creating a datatable object?
Dim dt as Datatable
dt.coloumns.add()
vs
Dim dt as Datatable = new Datatable
dt.coloumns.add()
Both seem to do the same things. However, in which scenario should I use new keyword? Are therere specific objects I don't need to use the new keyword? I understand that for common things like string, integer etc you don't need to instantiate the object. Is it the same case for DataTable too?
Dim dt as Datatable is merely declaration of the variable. It does not initialise it, so by default the value of dt is null (Nothing in VB I believe). Note that only declaring the value is not illegal at all, so you are perfectly within your rights to do so.
On the other hand, Dim dt as Datatable = new Datatable declares as well as initialises the variable. That is to say, new will initialise the declared variable with the appropriate value. If an class has a constructor which accepts parameters, then you can use new along with the constructor to create a new instance of that class and assign your chosen values to the class properties instead of using the default values.
The difference between your examples is that dt.Columns.add() will throw an error in the first example, since you are trying to call a method on a null object. In the second case, you have used new to provide an initial value to the variable. As a result, you can access the Columns property of a non-null object without any issue.
Now let's come to your other point - "I understand that for common things like string, integer etc you don't need to instantiate the object. Is it the same case for DataTable too?" Things like Integer are primitive datatypes, and so they have default non-null values. If you don't explicitly initialise with a value, they will take the default values. e.g. Dim x As Integer will automatically make x equal to 0
For objects, the default value is null, so it will cause problems if you try to do anything with that object without assigning a non-null value to it first. There are 2 ways to assign the non-null value:
Use new to initialise it.
Directly assign a value which is the result of some other processing in your code.

Understanding IEnumerator in VB.NET - reset

I'm having trouble understanding what's not happening, in my case, with IEnumerator in vb.net.
I have this code which pulls data from a database and then reads the first two rows, summing up a column from each row into 'numGirls'. Then, with 'resEnum1.Reset()', I expected 'resEnum' to reset itself to the begining of the collection, but it doesn't;
Dim resEnum1 As IEnumerator = iTrack.res_by_gender(False, YearCB.Text).GetEnumerator
resEnum1.Reset()
Dim resSet As Object
Dim numGirls As Integer = 0
For x = 0 To 1
resEnum1.MoveNext()
resSet = resEnum1.Current
numGirls += resSet.qty
Next
resEnum1.Reset()
At this point my code should continue and iterate through the collection starting at the begining of the collection (-1) with a MoveNext;
While resEnum1.MoveNext
'...........'
End While
However, the IEnumerator (resEnum1) does not infact get reset but continues from the third row of the collection. Why?
Obviously I'm not understaing something, unless it is up to me to re-invent the wheel and implement the 'reset' in code?
Not all enumerators implement the Reset method inherited from IEnumerator. You could think of it as a "forward-only" enumerator.
"The Reset method is provided for COM interoperability. It does not necessarily need to be implemented; instead, the implementer can simply throw a NotSupportedException.". - MSDN

VB.Net: Initialising variables with the New constructor

When initialising a list or a queue or a stack or anything similar, which method is preferred?
Dim q as Queue(Of Integer) = New Queue(Of Integer)
or
Dim q as New Queue(Of Integer)
Also, I've started to use New for string and integer variables - is this stupid? Is there any disadvantage to using New rather than just setting the variable to the default setting? E.g.
Dim Num1 As New Integer
Dim Str1 As New String("")
Dim Bool1 As New Boolean
Thank you!
If you'd ask programmers whether they like typing more or less when writing a program then the usual answer is "less!". If you ask them whether they like more or less bugs, the usual answer is "less!" Those are conflicting goals.
The As New syntax has been part of VB.NET for a very long time. It however does come with strings attached, you leave it entirely up to the runtime to figure out whether or not a new object should be created. That does tend to be a bug generator. Sometimes you really do want to create a new object, even though the variable is already assigned. It is also rather ambiguous, in this snippet for example:
For ix As Integer = 0 To 42
Dim q As New Queue(Of Integer)
'' etc...
Next
Question is: do you get one instance of the queue, created in the first pass of the loop or do you get 43 of them? What was actually intended by the programmer? It isn't very clear from the syntax.
There is a 3rd alternative that you overlooked and the one I prefer. Available since VB9 (aka VS2008) called "type inference". Where you don't specify the type of the variable but leave it up to the compiler to figure it out. This option needs to be turned on with Option Infer On, it is turned on by default. It combines the advantages of the abbreviated syntax that As New has and still lets you create the object explicitly in your code with the New statement:
Option Infer On
...
For ix As Integer = 0 To 42
Dim q = New Queue(Of Integer)
'' etc...
Next
Where q is inferred to be of type Queue by the compiler and it is crystal clear that the code generates 43 instances of the queue. The exact equivalent in the C# language is the var keyword.

Dynamically create variables in VB.NET

I have been trying to figure this out for some time now and can't seem to figure out an answer to it. I don't see why this would be impossible. I am coding in VB.NET.
Here is my problem:
I need to dynamically create variables and be able to reference them later on in the code.
More Details:
The number of variables comes from some math run against user defined values. In this specific case I would like to just create integers, although I foresee down the road needing to be able to do this with any type of variable. It seems that my biggest problem is being able to name them in a unique way so that I would be able to reference them later on.
Simple Example:
Let's say I have a value of 10, of which I need to make variables for. I would like to run a loop to create these 10 integers. Later on in the code I will be referencing these 10 integers.
It seems simple to me, and yet I can't figure it out. Any help would be greatly appreciated. Thanks in advance.
The best way to do something like this is with the Dictionary(T) class. It is generic, so you can use it to store any type of objects. It allows you to easily store and retrieve code/value pairs. In your case, the "key" would be the variable name and the "value" would be the variable value. So for instance:
Dim variables As New Dictionary(Of String, Integer)()
variables("MyDynamicVariable") = 10 ' Set the value of the "variable"
Dim value As Integer = variables("MyDynamicVariable") ' Retrieve the value of the variable
You want to use a List
Dim Numbers As New List(Of Integer)
For i As Integer = 0 To 9
Numbers.Add(0)
Next
The idea of creating a bunch of named variables on the fly is not something you are likely to see in any VB.Net program. If you have multiple items, you just store them in a list, array, or some other type of collection.
'Dim an Array
Dim xCount as Integer
Dim myVar(xCount) as String
AddButton Event . . .
xCount += 1
myVar(xCount) = "String Value"
'You will have to keep Track of what xCount Value is equal to to use.
'Typically could be an ID in A DataTable, with a string Meaning