Tom Shelton
11/18/2008 5:22:00 PM
On 2008-11-18, John Brock <jbrock@panix.com> wrote:
> I want to write a VB.NET subroutine that will take an input array
> of arbitrary type and resize it. Here is a trivial example of what
> I am trying to do:
>
> 'Increase the length of an arbitrary input array by one, using ReDim.
> Public Sub TryToReDim(ByRef ArrayIn As Object())
> ReDim Preserve ArrayIn(ArrayIn.Length)
> End Sub
>
> Actually what I really want -- because VB is so braindead when it
> comes to array manipulation -- is a Perl style Splice() routine,
> which of course would need to be able to resize the input array.
> I have a routine like that that works fine in VBA, but when I try
> to translate it to VB.NET I am tripped up by casting exceptions.
> Here is an example of the problem:
>
> Dim xxx() as String = {"aaa", "bbb", "ccc"}
> TryToReDim(xxx)
>
> This throws the following exception:
>
> InvalidCastException occurred
> Unable to cast object of type 'System.Object[]' to type 'System.String[]'.
>
> The problem is that, although the input variable ArrayIn is of type
> String[], ReDim, instead of redimensioning the array that was
> passed, creates a new, local array of type Object[], which then
> can't be assigned back to the original String[] input variable.
>
> So what can I do? For example, is there some way that, instead of
> using ReDim, I could examine the input array, determine its type,
> and create a properly sized local ArrayIn array of the same type,
> which could eventually be copied back without problems? I know
> that there is a such thing as Reflection in .NET, but it's not
> clear to me how that would apply in this case.
>
> For that matter, does VB.NET already have the equivalent of Splice()
> somewhere, which, for example, would allow me to insert an element
> into the middle of an array, without having to jump though hoops?
> I have never understood why it is so awkward to manipulate arrays
> in VBA and VB.NET! Does anyone have any idea why, after all this
> time, this hasn't been fixed?
Something like this:
Option Explicit On
Option Strict On
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim arr() As String = {"aaa", "ccc"}
Console.WriteLine("==================== Before ======================")
Array.ForEach(arr, AddressOf PrintElement)
Console.WriteLine("==================================================")
arr = Splice(Of String)(arr, "bbb", 1)
Console.WriteLine("===================== After ======================")
Array.ForEach(arr, AddressOf PrintElement)
Console.WriteLine("==================================================")
End Sub
Sub PrintElement(ByVal element As String)
Console.WriteLine(element)
End Sub
Function Splice(Of T)(ByVal arr() As T, ByVal item As T, ByVal index As Integer) As T()
Dim l As New List(Of T)(arr)
l.Insert(index, item)
Return l.ToArray()
End Function
End Module
That implementation of splice, is well very naive - there are no error checks
or anything :) But, as others have already said, I think what you really should
be looking at are Generics and the Generic colleciton classes. They are much
more flexible.
--
Tom Shelton