Different ways of declaring arrays - vb.net

Is there any difference in the two methods of declaring an array (see below code).
In the first method, I have declared the field nos as an Array Class type. Then I use it to point towards the memory space allocated for any type of array with 5 elements. Is this understanding correct?
Can a similar understanding not be applied to the second case also? That is because numbers has bee declared as numbers(), it becomes field of array type and thus can point towards any array that is being created. If that is so then is there any difference in these two ways of declaring the arrays??
Dim nos As Array
'Console.WriteLine(nos.GetType()) '>> Error: Object not set to reference
nos = New Integer(4) {}
Console.WriteLine(nos.GetType()) ' System.Int32[]
Dim numbers = New Integer(4) {}
Dim digits() = New Integer(4) {}
Console.WriteLine(numbers.GetType()) ' System.Int32[]
Console.WriteLine(digits.GetType()) ' System.Int32[]
Dim myArray(4) As Object
Console.WriteLine(myArray.GetType()) 'System.Object[]

Related

How to convert object to a string array in vb.net?

In my code I store a string array as an object inside a dictionary. Because that dictionary is a <string,object> type when I retrieve the value from dict like dict.item("string") it gives me only an object (obviously) but I need a string array. How to take it back now ?
I have seen many questions here,
they are like object array to string array, some are same of mine but in java, I need a one line code in Vb.net
edit :
code which stores the string array in to the dictionary
string_array[2] = {username, new system.Net.NetworkCredential(string.Empty, password).Password} ; out_Config(row("Name").ToString) = string_array
If you can't modify the dictionary to hold string arrays instead of objects (because it also holds other types) then you can cast the values back to string arrays from objects:
Dim dict As New Dictionary(Of String, Object)
dict.Add("item", New String() {"1", "2"})
Dim stringArray = CType(dict("item"), String())

Remove an object from a List(of) based on object value

How do I remove an object from a list based on value, I'me getting an index out of range error
'A class called Person exists'
Dim PersonOne As New Person
PersonOne.name = "John"
PersonOne.age = 50
'Created a list to store them'
Dim MyList As New List(Of Person)
MyList.Add(PersonOne)
'Now to remove an object'
Dim ObjectToRemove As String = "John"
For Each item in MyList
If String.Compare(item.name, ObjectToRemove) = 0 Then
'How do I get the index to remove?'
End If
Next
Excuse the code, I bashed it out off the top of my head, my original code is a bit more convoluted. But the gist is I just want to compare a value, if it matches remove that . object from the List(Of).
Use the FindIndex method which accepts a predicate delegate. You can pass a lambda function for the predicate delegate.
(Also, I think it's clearer to use String.Equals with an explicit StringComparison instead of using String.Compare(x,y) == 0 as it signals intent better).
Dim personOneHasThisIndex As Integer
personOneHasThisIndex = MyList.FindIndex( Function(p) p.name.Equals( ObjectToRemove, StringComparison.Ordinal ) )
If personOneHasThisIndx > -1 Then
' Always check if the result is -1, which means it doesn't exist
MyList.RemoveAt( personOneHasThisIndex )
End If
Note that List<T>.RemoveAt(Int32 index) is inefficient because it has to move every element in the List (lists cannot have "empty" spaces). If you have a conceptual list you'll be adding and removing from a lot, consider using LinkedList or a HashSet (if the order of the elements doesn't matter) instead.

Sorting a collection of objects in VBA

I'm trying to write a function that would sort a collection of objects. Since the objects are all of the same type (the same user-defined class), their property set is the same. Is it possible to discover the object's properties (through code) so as to put the collection in a bi-dimensional array, each row being for an object, each column for one of its property?
Another solution would be to copy each object from the collection to an array of objects, and sort them by one of their property, whose name is passed to the function as a string. But I don't see how I can point to the object's property using the property's name passed as a string.
For a collection, it is best to sort it by it's Keys (that's what they're there for) -- but in case you don't have the keys list (lost your keys!):
'Give an input "Data As Collection"
Dim vItm As Variant
Dim i As Long, j As Long
Dim vTemp As Variant
For i = 1 To Data.Count – 1
For j = i + 1 To Data.Count
If CompareKeys(Data(i).myMemberKey, Data(j).myMemberKey) Then
'store the lesser item
vTemp = Data(j)
'remove the lesser item
Data.Remove j
're-add the lesser item before the greater Item
Data.Add vTemp, , i
End If
Next j
Next i
Come up with your own CompareKey function which will return true or false if the UDT member variables are >, < or 0 to one another. The reason you have to delete and re-add is because you cannot 'swap' internal members in a vb6/vba collection object.
Best of luck
EDIT:
To access a property you have the name of programmatically (as a string), use VB's CallByName function in the form:
Result = CallByName(MyObject, "MyProperty", vbGet)

How do you assign values to structure elements in a List in VB.NET?

I have a user-defined structure in a list that I am trying to change the value for in an individual element within the list of structures. Accessing the element is not a problem. However, when I try to update the value, the compiler complains:
"Expression is a value and therefore cannot be the target of the
assignment"
For example:
Public Structure Person
Dim first as String
Dim last as String
Dim age as Integer
End Structure
_
Public Sub ListTest()
Dim newPerson as Person
Dim records as List (Of Person)
records = new List (Of Person)
person.first = "Yogi"
person.last = "bear"
person.age = 35
records.Add(person)
records(0).first = "Papa" ' <<== Causes the error
End Sub
As the other comments said, when you refer to records(0), you get a copy of the struct since it is a value type. What you can do (if you can't change it to a Class) is something like this:
Dim p As Person = records(0)
p.first = "Papa"
records(0) = p
Although, I think it's just easier to use a Class.
There are actually two important concepts to remember here.
One is that, as Hans and Chris have pointed out, Structure Person declares a value type of which copies are passed between method calls.
You can still access (i.e., get and set) the members of a value type, though. After all, this works:
Dim people(0) As Person
people(0).first = "Yogi"
people(0).last = "Bear"
people(0).age = 35
So the other important point to realize is that records(0) accesses the List(Of Person) class's special Item property, which is a sugary wrapper around two method calls (a getter and setter). It is not a direct array access; if it were (i.e., if records were an array), your original code would actually have worked.
I had the same problem, and I fixed it by adding a simple Sub to the structure that changes the value of the property.
Public Structure Person
Dim first as String
Dim last as String
Dim age as Integer
Public Sub ChangeFirst(value as String)
me.first = value
End Sub
End Structure

Declaring a byte array in VB.NET

When declaring a byte array, what is the difference between the following? Is there one, or are these just two different ways of going about the same thing?
Dim var1 As Byte()
Dim var2() As Byte
There's no difference.
Quotes from the spec (2003 spec, but same in the 2010 spec as can be downloaded here):
Array types are specified by adding a modifier to an existing type name.
A variable may also be declared to be of an array type by putting an array type modifier or an array initialization modifier on the variable name.
For clarity, it is not valid to have an array type modifier on both a variable name and a type name in the same declaration.
And below is the sample from the spec that shows all the options:
Module Test
Sub Main()
Dim a1() As Integer ' Declares 1-dimensional array of integers.
Dim a2(,) As Integer ' Declares 2-dimensional array of integers.
Dim a3(,,) As Integer ' Declares 3-dimensional array of integers.
Dim a4 As Integer() ' Declares 1-dimensional array of integers.
Dim a5 As Integer(,) ' Declares 2-dimensional array of integers.
Dim a6 As Integer(,,) ' Declares 3-dimensional array of integers.
' Declare 1-dimensional array of 2-dimensional arrays of integers
Dim a7()(,) As Integer
' Declare 2-dimensional array of 1-dimensional arrays of integers.
Dim a8(,)() As Integer
Dim a9() As Integer() ' Not allowed.
End Sub
End Module
And as can be seen in the comments, a1 and a4 does the same thing.
They're the same thing. You can verify by looking at the compiled code in reflector, or by writing that code in the IDE, then hovering your mouse over each.
They're reported as "var1() as byte" and "var2() as byte"
even though the first was declared with the alternate syntax.