Object Array shenanigans

I have a shared method into which I pass arrays of controls (mix of rectControls and containerControls) to effect alignment. I was previously using variant arrays and sometimes had problems when there was only one type of item in the array - the compiler would then seem to auto format as a array of the item’s type, rather than a variant array.

So instead I though I’d use an Object() array, thinking this would fix the problem as all the controls are subclasses of objects.

Dim objs() As object 
objs = Array(tbClosed, eDueDate)
//where tbClosed is a canvas subclass and
//eDueDate is a containterControl subclass

But now the compiler gives an error stating “Type mismatch error. Expected Object() but got Variant().” I suppose this is the compiler doing its thing again.

So I tested the alternative of:

Redim objs(-1)
objs.append tbClosed
objs.append eDueDate

This doesn’t give a compile error but would require a significant amount of re-coding on all the controls I have (100’s of controls).

Any ideas?

Instead of object, use variant for the array declarations.
Same thing, but less hassle.

That is normal for array function.
But you can put first value into variant first to make sure you get that type.

DRY Don’t Repeat Yourself is not about coding but maintenance: perfect example. You may subclass your controls…

Have a nice day :grinning:

Perhaps the easiest workaround, instead of rewriting your whole method, could be to add a dummy object, like:

Var dt as DateTime=DateTime.Now
Var MyArray() As Variant=Array(dt,PushButton1,CheckBox1)

That way you guarantee the array is never converted; you just skip the first item when dealing with the array. Note I’m note sure this syntax is accepted (not in front of Xojo right now). You may try appending “dt” later, if it works better.

Yes, ugly, but still a workaround (for a problem that shouldn’t be there in the first place, IMO).

While I have never used it with variants, I have found the array function frustrating because it’s assumptions about integer types…

One way is to have have the compiler look at what the array is being assigned to determine array type instead of the first element…

Another way of doing this for situations like these in a more verbose API2ish way could be something like:

Dim theArray() as Datatype = DataType.Array(Item1, item2, Item3, …)

Dim Uint8Array() as Unit8 = Uint8.Array(5,10,15)
Dim Int32() as Int32 = Int32.Array(5,10,15)
Dim VarArray() As Variant = Variant.Array(Item1, item2, Item3, …)

And for this syntax, even though the current function is fine in this case, just to be consistent maybe also support:
Dim MyClassArray() as MyClass = MyClass.Array(Inst1, Inst2, Inst2)
Dim MyStructArray() as MyStruct = MyStruct.Array(item1, Item2, item3)

-Karen

Karen - this looked good, but gives a syntax error. ??

This did work thanks Christian. My example code becomes:

objs = Array(variant(tbClosed), eDueDate)

A bit ugly but saves a heavy re-write.

Thanks Sebastien. Yes the controls are all subclassed already. But I have them in varying groups and alignments dependent upon other selections.

1 Like

I also tried this Arnaud, but each time I compile a different array into the variable it fails again, despite the type of the array when originally dim’d (var’d?).

That was one way they COULD implement that as a feature if they wanted to… It does not exist now.

-karen

Ah, understand. Yes that would be useful.

That’s because you’re throwing away the array you just dim’d and replacing it with an entirely new array which could be of any type.

Ahem, maybe I spoke too soon. My initial tests worked but subsequent tests don’t always. See code:


Dim cc As New ContainerControl
Dim cv As New canvas

Dim v1() As Variant
v1 = Array(cc, cv) //works

Dim v2() As Variant
v2 = Array( Variant(cc), cv)  //type mismatch

Oh for some consistency!!

Perhaps for the sake of your existing code, you could create a global method

Function Array2(paramarray a() as variant) as variant()
   Return a
End Function

Then you just have to change Array to Array2 in your code.

Ah, now that is clever. Thanks Tim.