There are times when a method needs to work on an array and you’d like to call it as either M(1, 2, 3 )
or M( Array( 1, 2, 3 ) )
. If the array is a defined type, you can overload, but what if it’s a Variant array? If you overload, you might access the ParamArray version or you might get the “straight” array version. And what if you do want to feed the method any type of array? And what if you have a base method that other methods that also take a ParamArray might access?
The solution is to have just the ParamArray and a function like this:
[code]Private Function GetTrueValues(values As Variant) as Variant()
//
// A ParamArray might embed the true array inside another array
// so will drill down and extract that
//
dim result() as variant
if values.IsNull then
return result
end if
dim autoValues as auto = values
do
dim ti as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( autoValues )
select case ti.FullName
case “Date()”
dim arr() as Date = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Xojo.Core.Date()"
dim arr() as Xojo.Core.Date = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Object()" // Can't ever really be an object
result = autoValues
if result.Ubound = 0 and result( 0 ).IsArray then
autoValues = result( 0 )
continue do
end if
case "String()"
dim arr() as string = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Text()"
dim arr() as text = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Integer()"
dim arr() as integer = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Int32()"
dim arr() as Int32 = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Int64()"
dim arr() as Int64 = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Double()"
dim arr() as double = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Single()"
dim arr() as single = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Currency()"
dim arr() as currency = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
case "Boolean()"
dim arr() as boolean = autoValues
redim result( arr.Ubound )
for i as integer = 0 to arr.Ubound
result( i ) = arr( i )
next
end select
//
// If we get here, we've processed as much as we can
//
exit do
loop
return result
End Function
[/code]
You can then write your functions like this:
Sub M (ParamArray values() As Variant)
values = GetTrueValues( values )
...
End Function
Sub M1 (ParamArray values() As Variant)
M( values ) // This will work just fine
End Sub