Tried several variations, but I either get a TypeMismatch exception or don’t find a logical way…
I have a variable of type variant (can’t avoid variants in my case).
This variable may hold anything, including a single-dimensional array. I have to write its content to a BinaryStream.
My current code works fine as long as the variant doesn’t hold an array of objects:
dim j As Integer if bs<>nil then j=VarType(Value) bs.WriteInt32 j Select case j case 11 'Boolean bs.WriteBoolean Value case 9 'Object if Value isa Point then bs.WriteInt8 16 bs.WriteDouble Point(Value).X bs.WriteDouble Point(Value).Y elseif Value isa Picture then bs.WriteInt8 21 bs.WritePicture Value Else bs.WriteInt8 0 dim ex As new RuntimeException("Object type not yet supported.",-50) Raise ex end if case 5 'Double bs.WriteDouble Value
(and so on for non-array values. Next, for arrays:)
case 4106 'Array of booleans dim ac,ai As Integer dim av() As Boolean av=Value ac=av.LastIndex bs.WriteInt32 ac for ai=0 to ac bs.WriteBoolean av(ai) next bs.WriteInt8 39 'Marker case 4098 'Array of integers dim ac,ai,av() As Integer av=Value ac=av.LastIndex bs.WriteInt32 ac for ai=0 to ac bs.WriteInt32 av(ai) next bs.WriteInt8 39
But, for an array of objects, I have to know which class of objects it holds so I can save each object accordingly.
VarType doesn’t know about my custom classes, so it’s out. I don’t think introspection is good for that either. “IsA” doesn’t work for an array, since it would return the fact it’s an array. I haven’t found another function.
My current code looks like this (but doesn’t work):
case 4105 'Value contains an array of objects dim vl() as Variant vl=Value if UBound(vl)=-1 then 'Empty. Write “9” to the stream (when read back, “9” will have this meaning) bs.WriteInt8 9 Else for each v as Variant in vl bs.WriteInt8 1 //One more object to write WriteVariantToStream bs,v //Recursion with only a single object next bs.WriteInt8 0 //No more objects to save end if
This compiles fine, but I get a TypeMismatch exception at “vl=Value”, because vl is an array of variants and Value is an array of MyCustomClass.
I could have code like this:
dim vp() as Point dim vm() as MyClass dim vi() as Picture if UBound(Value)=-1 then 'Empty else dim v as Variant=Value(0) 'Now I know the type hold in the array select case true case v isa Point vp=Value //Save each point case v isa MyClass vm=Value //Save each object case v isa Picture ci=Value //Save each picture …
But this looks clunky.
I’m missing something obvious or it just must be clunky like that?