views:

3304

answers:

7

Here I have:

Public Structure MyStruct
   Public Name as String
   Public Content as String
End Structure

Dim oStruct as MyStruct = New MyStruct()
oStruct.Name = ...
oStruct.Content = ...

Dim alList as ArrayList = new ArrayList()
alList.Add(oStruct)

I'd like to convert the ArrayList to a static strongly-typed Array of type MyStruct. How can I do that? I had no luck with ToArray.

I am using .NET Framework 2.0.

+4  A: 

You have to cast the result of ToArray

MyStruct[] structs = (MyStruct[]) alList.ToArray(typeof(MyStruct));
Bill the Lizard
+1  A: 

I assume that since you are using ArrayList, you are using 1.1?

In which case, I suspect the following would work:

ArrayList list = new ArrayList();
MyStruct[] array = new MyStruct[list.Count];
list.CopyTo(array);

(edit - Bill's ToArray usage is more convenient - I didn't know about that one, but then, I very rarely [if ever] use ArrayList)

However, if MyStruct really is a struct, then I cannot say strongly enough that mutable structs are a bad idea - i.e. where you can set .Name and .Content after creation. Structs should almost always be immutable. In reality, your MyStruct looks like it should be a class. Also - I'm not "up" on VB, but are they public fields? Again - not recommended - properties would be preferable. I don't know about VB, but C# 3.0 has some very terse syntax for this:

public class SomeType
{
    public string Name {get;set;}
    public string Content {get;set;}
}

If you are using 2.0 or above, consider List<T> instead of ArrayList.

Marc Gravell
I didn't knew ArrayList was 1.1.Problem is that I need to code it in VB.NET, so I'm not sure I can use List<T>.
Vincent
I'm pretty certain that VB.NET can use generics; MSDN has a VB example here: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
Marc Gravell
I got it with List(Of MyStruct).
Vincent
+1  A: 

ToArray is the right way to go. In C# it would be:

MyStruct[] array = (MyStruct[]) alList.ToArray(typeof(MyStruct));

Are you stuck using 1.1, btw? If you're using 2.0, can you shift to List<T> instead?

Jon Skeet
A: 

This worked for me

Dim array As MyStruct() = alList.ToArray(GetType(MyStruct))
Lou Franco
A: 

If you are running Visual Studio 2008 you can use a List object.

  Dim alList As New List(Of MyStruct)
  alList.Add(oStruct)
John Chuckran
You can do this in .Net 2.0 (vs2005) as well.
Joel Coehoorn
A: 

In case you're using 2.0 or later, you might want to define your arraylist like this:

Dim alList as New List(Of MyStruct)()
alList.Add(oStruct)

This will give you the same semantics as an array (lookup by index, strong typing, IEnumerable support, etc).

There are only two reasons in .Net 2.0 and later to use an array instead of a generic list:

  1. You know with absolute certainty the number of items you have, and know that the count won't change. This is surprisingly rare.
  2. You need to call a function that requires an array. There are still a fair number of these lurking in the BCL, but your own code should be asking for IEnumerable<T>, IList<T>, or ICollection<T>, and only rarely an array.

Finally, this is kind of nit-picky, but there are two stylistic points I want to address in the code you posted. First, note the abbreviated syntax I used to create the New List<MyStruct>. There's no = symbol and you don't have to key in the type name twice. That was support back in 1.1 as well, so there's no excuse there. Secondly, the style guidelines for .Net published by Microsoft on MSDN (see the general naming conventions section) specifically recommend against hungarian warts like 'o' or 'a'. It was nice for VB6/VBScript, which were loosely typed, but .Net is strongly typed, making the warts, well, wart-ugly.

Joel Coehoorn
A: 

Thank you all for your answers! I really feel like a stupid .NET developer today! :)

Vincent