Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > .NET General

Vista - Is there a way to resize an array from inside a procedure? Using Reflection maybe?

Reply
 
Old 11-17-2008   #1 (permalink)
John Brock


 
 

Is there a way to resize an array from inside a procedure? Using Reflection maybe?

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?
--
John Brock
jbrock@xxxxxx


My System SpecsSystem Spec
Old 11-18-2008   #2 (permalink)
Michel Posseth [MCP]


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

Quote:

> "VB is so braindead when it comes to array manipulation"
Just one question did you ever noticed the array class , in the .Net
Framework ?
imho
VB and C# are masters with array manipulation


http://msdn.microsoft.com/en-us/libr...tem.array.aspx

resizing with the array class

http://msdn.microsoft.com/en-us/library/bb348051.aspx

and lots and lots more

The exception that you encounter is obvious , you might be bether of with
generics in your case


HTH

Michel Posseth



"John Brock" <jbrock@xxxxxx> schreef in bericht
news:gftga1$f9a$1@xxxxxx
Quote:

>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?
> --
> John Brock
> jbrock@xxxxxx
>

My System SpecsSystem Spec
Old 11-18-2008   #3 (permalink)
Armin Zingler


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

"John Brock" <jbrock@xxxxxx> schrieb
Quote:

> I want to write a VB.NET subroutine that will take an input array of
> arbitrary type and resize it.
It is not possible to resize an array. Not in VB.Net, not in any other .Net
Framework based language. Read also the documentation on Redim Preserve. It
creates a new array as you've already pointed out below on your own.

Use one of the many other helpful collections:
http://msdn.microsoft.com/en-us/library/7y3x785f.aspx
(maybe before all "commonly used collections")
Quote:

> Dim xxx() as String = {"aaa", "bbb", "ccc"}
> TryToReDim(xxx)
>
> This throws the following exception:
No, It can not be compiled. Enable Option Strict On! "It might work" is not
good enough.


Armin

My System SpecsSystem Spec
Old 11-18-2008   #4 (permalink)
Michael C


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

"John Brock" <jbrock@xxxxxx> wrote in message
news:gftga1$f9a$1@xxxxxx
Quote:

> 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?
The problem is not VB, it's your approach. The array is a fixed size block
of memory as Armin pointed out. You should be using one of the many
collection classes if you want to insert items in the middle of a list. Most
likely the List class is what you need as it has an insert method. The list
class is generic so can be created as type string

Dim list as New List(Of String)
list.add("Aa")
list.add("ba")
list.add("va")
list.add("da")
list.Insert("aaaa", 3")

Michael


My System SpecsSystem Spec
Old 11-18-2008   #5 (permalink)
PvdG42


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?


"John Brock" <jbrock@xxxxxx> wrote in message
news:gftga1$f9a$1@xxxxxx
Quote:

>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?
> --
> John Brock
> jbrock@xxxxxx
>
Brain dead? As you've been told, you need exposure to the various
collections classes in .NET.
It's easy to convert your array to a List<>, then do any resizing needed,
then convert the List<> back to an array if you must have it as an array.
Look up the collections classes in MSDN and observe all the management
methods available.

My System SpecsSystem Spec
Old 11-18-2008   #6 (permalink)
Tom Shelton


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

On 2008-11-18, John Brock <jbrock@xxxxxx> wrote:
Quote:

> 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
My System SpecsSystem Spec
Old 11-18-2008   #7 (permalink)
John Brock


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

In article <20C1914E-56BC-4D44-8AED-A3BDCADC8E7E@xxxxxx>,
PvdG42 <pvdg42@xxxxxx> wrote:
Quote:

>Brain dead? As you've been told, you need exposure to the various
>collections classes in .NET.
>It's easy to convert your array to a List<>, then do any resizing needed,
>then convert the List<> back to an array if you must have it as an array.
>Look up the collections classes in MSDN and observe all the management
>methods available.
Um, I think "braindead" is in fact the appropriate word here. Your
suggestion will certainly work, but it's a pain. In fact it is
actually an perfect example of just the sort of hoop I've been
hoping to avoid having to jump through when it comes time to do
anything with arrays.

It's always possible I've missed something though. An example
might be helpful! Let's say that, for the array below, I wanted
to insert an additional element, "xxx" perhaps, in the second
position. Is there a one line VB.NET statement that will do this?
(If possible the statement should be general, so that it will work
equally well if I want to use it for an array of Integers, or other
types).

Dim xxx() as String = {"aaa", "bbb", "ccc"}

This is something which is trivially easy in Perl, and, IMO, ought
to be easy in any well designed language. If you can't come up
with a one line example, then a two or three line example would
also be welcome. Actually, I'd be interested in seeing how you
would handle this situation if it came up in your own code.

Don't tell me though that I ought to be using lists instead of
arrays. For one thing, I might be dealing with existing code, and
not have that option. In any case, unless you are saying arrays
in .NET are totally deprecated and should never be used, there is
always the possibility that you will find yourself using arrays
because they are the best choice for a particular situation, and
then finding that you need to insert elements into the middle of
those arrays. So how -- in a general way -- does one do that?

If in fact there is no easy way I'd still be interested in knowing
why. It's possible there is some deep legacy issue which prevents
Microsoft from making the obvious additions to the language, but
I'd be interested in knowing what that issue is.
--
John Brock
jbrock@xxxxxx

My System SpecsSystem Spec
Old 11-18-2008   #8 (permalink)
Armin Zingler


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

"John Brock" <jbrock@xxxxxx> schrieb
Quote:

> Is there a one line VB.NET statement that will do this?
> (If possible the statement should be general, so that it will work
> equally well if I want to use it for an array of Integers, or other
> types).
>
> Dim xxx() as String = {"aaa", "bbb", "ccc"}
>
> This is something which is trivially easy in Perl, and, IMO, ought
> to be easy in any well designed language. If you can't come up
> with a one line example, then a two or three line example would
> also be welcome. Actually, I'd be interested in seeing how you
> would handle this situation if it came up in your own code.
I'm sure you are right that this is easy with Perl. I don't know Perl.
However, as there are other ways to do what you want in the .Net world, why
do you insist on doing it with an array? It is as if I'd use Perl and insist
on using a List(Of) there but it doesn't exist.

You've simply chosen the wrong type for your purposes.


Armin

My System SpecsSystem Spec
Old 11-18-2008   #9 (permalink)
Armin Zingler


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

> You've simply chosen the wrong type for your purposes.

I mean, you have made a wrong translation. "Array" in the Perl language
translated to VB.Net is "List(Of)". You translated it to "Array". That's
obviously wrong.


Armin

My System SpecsSystem Spec
Old 11-18-2008   #10 (permalink)
Tom Shelton


 
 

Re: Is there a way to resize an array from inside a procedure? Using Reflection maybe?

On 2008-11-19, John Brock <jbrock@xxxxxx> wrote:
Quote:

> In article <20C1914E-56BC-4D44-8AED-A3BDCADC8E7E@xxxxxx>,
> PvdG42 <pvdg42@xxxxxx> wrote:
>
Quote:

>>Brain dead? As you've been told, you need exposure to the various
>>collections classes in .NET.
>>It's easy to convert your array to a List<>, then do any resizing needed,
>>then convert the List<> back to an array if you must have it as an array.
>>Look up the collections classes in MSDN and observe all the management
>>methods available.
>
> Um, I think "braindead" is in fact the appropriate word here. Your
> suggestion will certainly work, but it's a pain. In fact it is
> actually an perfect example of just the sort of hoop I've been
> hoping to avoid having to jump through when it comes time to do
> anything with arrays.
>
Are you saying learning about the collection classes are unneeded hoops?
Quote:

> It's always possible I've missed something though. An example
> might be helpful! Let's say that, for the array below, I wanted
> to insert an additional element, "xxx" perhaps, in the second
> position. Is there a one line VB.NET statement that will do this?
> (If possible the statement should be general, so that it will work
> equally well if I want to use it for an array of Integers, or other
> types).
>
> Dim xxx() as String = {"aaa", "bbb", "ccc"}
>
> This is something which is trivially easy in Perl, and, IMO, ought
> to be easy in any well designed language. If you can't come up
> with a one line example, then a two or three line example would
> also be welcome. Actually, I'd be interested in seeing how you
> would handle this situation if it came up in your own code.
>
I believe that perl implements it's "arrays" internally as a linked list. Not
a C-style fixed size chunk of memory. In .NET, Arrays are essentially that -
fixed chunk of memory.

If you insist on using arrays rather then the collection classes (such as
List(Of T)) then you will want to understand this implementation so that you
can efficiently work with them. First, you should understand what ReDim does,
it creates a new array - basically it allocates a new chunk of memory, and if
you specify preserve, then it copies the values of the old array to the new
array. That's fine and good, but is very inefficient if you are going to make
a lot of calls to ReDim. So, you will want to grow the array more then needed
to keep the calls to ReDim to a minimum. The common algorith is to increase
the size by 10% of the current size with each allocation.

Of course, this posess a problem... Because the size of the array and the
number of elements are out of sync - so, you probably will want to introduce
a variable to keep track of the actual number of values stored in the array.

Another consideration is the addition and removal of items. Generally, that
means shifting things around - either up or down in the array, setting the
unused slots to nothing, and then updating your element counter...

It's a lot of work, so, to keep from making a mistake, you might want to wrap
this all in a class that can handle the management of the array. Then provide
a method to get an actual array when you need it.

Oh, or you could just use List(Of T) - because that's exactly what it does.
List(Of T) is a wrapper for an array, that handles all of the managment
details for you.
Quote:

> Don't tell me though that I ought to be using lists instead of
> arrays.
See above - and it's trivial to go to and from a list to an array. List(Of T)
takes an IEnumerable(Of T) in one of it's constructors (which System.Array
implements) and it has a .ToArray method.
Quote:

> For one thing, I might be dealing with existing code, and
> not have that option.
See above.
Quote:

> In any case, unless you are saying arrays
> in .NET are totally deprecated and should never be used, there is
> always the possibility that you will find yourself using arrays
> because they are the best choice for a particular situation, and
> then finding that you need to insert elements into the middle of
> those arrays. So how -- in a general way -- does one do that?
>
> If in fact there is no easy way I'd still be interested in knowing
> why. It's possible there is some deep legacy issue which prevents
> Microsoft from making the obvious additions to the language, but
> I'd be interested in knowing what that issue is.
The fact that arrays in .NET are arrays, and not linked lists? Arrays are
very effiecient - if they don't need to be changed much. If the data is not
static in it's size, then managing an array in an efficient manner becomes a
not so trivial exercise... Hence, System.Collections.ArrayList and
System.Collections.Generic.List(Of T) - you should prefere List(Of T) over
ArrayList in new code because of the improved functionality and the
performance benifits of generics.

HTH

--
Tom Shelton
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
How to programmatically resize the height of a custom IE toolbarwritten in C#? When I resize it, it shrinks but the real-estate it is in staysthe same size. .NET General
VB script - for accessing a array returned from stored procedure VB Script
how to retrieve an array returned from stored procedure VB Script
Property Set procedure with a structure array .NET General
can't remember how to resize an array PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46