Array of Type conversions?

BlitzMax Forums/BlitzMax Beginners Area/Array of Type conversions?

Mahan(Posted 2008) [#1]
Hi!

As a complete newbie at BlitzMax I've been trying to get a hang of conventions and patterns to use. So this is a little thing I've encountered several times:

The TList class has a .ToArray() method that returns an array of Object (Object[]). Problem is that arrays in BlitzMax seem typed to their base type and not compatible with arrays of another type (if i grasp things right). I've found no direct way of making Object[] to become a String[] without making a new array of the desired type and copy the data in. (i.e. casting did not work out for me)

So I've written this little function below to at least automate the copying part for me, but my question to the pro BlitzMax developers out there is: Is there an even easier way to do this or is the copying the way to go?




edit: spelling


tonyg(Posted 2008) [#2]
This worked pre-1.18. It was reported but I don't think anything came of it. Recasting the array is the only way I think.


Otus(Posted 2008) [#3]
You are probably better off enumerating the TList directly when adding to the custom array - creating an Object[] array is an unnecessary step, at least in your example.

Something like (untested):
Function ListToArrayOf:Object(list:TList, of:TTypeId)
	Local arrayType:TTypeId = of.ArrayType()
	Local result:Object = arrayType.NewArray( list.Count() )
	Local idx:Int = 0
	For Local obj:Object = EachIn list
		arrayType.SetArrayElement result, idx, obj
	Next
	Return result
End Function


Anyway, if you know the target type before runtime, you should probably not use reflection, but have a specific function for each type you need to use.


Mahan(Posted 2008) [#4]
Good point Otus!

Haven't tested your code eighter, but i think i spotted a missing idx incrementation somewhere. However you're right that if this function is supposed to work with TList only, then it's faster to go against the list in the first place. I'll happily copy your idea :)

I used reflection because I intend to group my utility functions in a .bmx for usage in several projects and I need code that will work with types yet to be invented. Until we get some kind of templates (like in c++) or generics (java/C#) i think its the only way to deal with types not known at designtime. I should probably add a note to all my functions using reflection about the performance hit so I dont use them in the "inner loop" and/or with huge numbers of objects.


kfprimm(Posted 2008) [#5]
Local strarray$[]=String[](list.ToArray())

Does that not work?


Mahan(Posted 2008) [#6]
Depends on how you define "does work" ;)

SuperStrict


Local list:TList = New TList
list.addLast("hi")
list.addLast("there")

Print "List count: " + String.FromInt(list.count())

Print "List.ToArray().length: " + String.FromInt(List.ToArray().length)

Local strArray:String[]=String[](list.ToArray())

Print "Resulting array length: " + String.FromInt(strArray.length)


It compiles but produces this output:

List count: 2
List.ToArray().length: 2
Resulting array length: 0