Tip: ParamArray or array of Variant

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