Empty array of a type can’t be checked with `IsA` not returned in a Variant

I have this code:

Class cClass
End Class
    
Class cClassSub
  Inherits cClass
  Public pText As String
End Class

Function Test() As cClass()
  Var oEssais() As cClassSub
  Var vVariant As Variant
  Var vSuccess As Boolean
  
  vVariant = oEssais
  
  If vVariant IsA cClass Then 
    vSuccess = True // No
  Else
    vSuccess = False // Yes…
  End If
  
  // Return oEssais : Works
  Return vVariant // Fails
End Function

If my array was not empty, it would work as intended, but with an empty array, the IsA and the Return fails. Is this a bug, or should I do a feature request?

Regards, Antoine

oEssais is not an object of a Class, it’s an Array (of objects of a class).

Maybe there lies your problem.

Also beware about non-instantiated objects that carries a NIL value before that.

While debugging, use Vartype() to watch how things are being classified.

K. VarType() will not help me, I know it’s an Array. I want to know the type of elements the array contains.
How can I know that? Should I use the Introspection?

Also, my problem is also with the Return.
Why the Variant doesn’t convert?

Function Test() As cEssais()
  Var oEssais(), vEssai As cEssaisSousClasse
  Var vVariant As Variant
  Var vRes As Boolean
  
  vVariant = oEssais
  
  'Return vVariant // Fails
  
  vEssai = New cEssaisSousClasse()
  
  vRes = vEssai IsA cEssais
  // vRes = True
  
  oEssais.Add(vEssai)
  vVariant = oEssais
  
  'Return vVariant // Fails
  Return oEssais // Works
End Function

Shouldn’t the Return vVariant work?

Regards, Antoine

The runtime doesn’t know the type.
It’s basically an array of object.

Better say what you want to input into the function and what you want as output.

I want to output an array of subclassed objects, typecasted to the superclass…

A.

I don’t understand. My variable is very defined. It’s type is an Array of cEssaisSousClasse.
Var oEssais() As cEssaisSousClasse

Regards, Antoine

Class MySuperClass
End Class
  
Class MySubClass1
  Inherits MySuperClass
End Class

Class MySubClass2
  Inherits MySuperClass
End Class

Public Function MyArrayOfSubClasses() As MySuperClass()

  Var myArraysSubs() As MySuperClass // Array of SuperClass
  
  myArraysSubs.Add New MySubClass1   // Add One Sub
  myArraysSubs.Add New MySubClass2   // Add Another Sub
  
  Return myArraysSubs                // Return the array
  
End Function

It just doesn’t work that way in Xojo due to the way it handles Arrays - you can’t typecast an Array in any meaningful way, so there’s no way to return subClass() when the return type is superClass(). Arrays, no matter what the type of their contents, are always type peers and never sub- or super-classes of each other.

You’ll have to convert your array of subclass objects like this:

dim resultArray() as superClass

for each currentSubClassObject in subClassObjects()
   resultArray.Add superClass(currentSubClassObject)
next

return resultArray

I guess I’m not understanding you.

My sample does what he asked. Return an array of superclass with subclass objects (that can differ)

Later he can identify each content as

Var arrayReturned() As MySuperClass = MyArrayOfSubClasses()  // get array

For Each item As MySuperClass in arrayReturned
  
  If item IsA MySubClass1 Then
    
    System.DebugLog "Received a MySubClass1"
    
  ElseIf item IsA MySubClass2 Then
    
    System.DebugLog "Received a MySubClass2"
    
  End
  
Next

Break

1 Like

I was replying to him, not you, to try and fill in what looks like a gap in his understanding of how arrays work in Xojo.

This will never be true. At this point, oEssias is Nil, so you have assigned Nil to vVariant. It is most certainly not a cClass.

But you interrupted an answer to introduce a noise, probably leading to error, or at least misunderstandings, as I can’t understand what you wrote in a positive way until now. So I couldn’t keep quiet seeing such thing, then showed the use of what, for me, you said it was impossible.

So in essence the OP needs to check for Nil before doing the IsA.

And unpacking things… etc.

Better just rewrite what he said he intends to do in a simpler way without variants, as shown.

What he MAY need AFTER is to check

If arrayReturned.Count = 0 if he intends some different processing if nothing was returned IN the array.

No the IsA operator will handle Nil.

x IsA ClassType will always be false when x is nil.

Thanks for that - it was new to me as I rarely use IsA.

I don’t think (and Xojo at runtime) that an empty array is null…

Function Test() As cEssais()
  Var oEssais(), vEssai As cEssaisSousClasse
  Var vVariant As Variant
  Var vRes As Boolean
  
  vEssai = New cEssaisSousClasse()
  
  vRes = vEssai IsA cEssais
  // vRes = True
  
  oEssais.Add(vEssai)
  vVariant = oEssais
  oEssais = vVariant
  
  vRes = vVariant.IsNull()
  // vRes = False
  
  vRes = vVariant.IsArray()
  // vRes = True

  Return vVariant // Fails
  Return oEssais // Works
End Function

After line vRes = vVariant.IsNull(), vRes is False.
After line vRes = vVariant.IsArray(), vRes is True.

And this line doesn’t do errors, so it proves that the conversion is possible:
oEssais = vVariant

My real problem here is this line at the end:
Return vVariant // Fails

Regards, Antoine

@Mike_D, @Rick_Araujo, @Eric_Williams, @Christian_Schmitz: thank you for taking the time to reply.

I was not clear, since I had 3 different issues in this post. So I will them post separately so it’s clearer. My problem is that I have to return a Variant, and if it’s a Variant containing an empty array, it generates a runtime error, but if the conversion is done when not through the return statement then it works…

Also, see the debugger pane, Xojo knows at runtime that it’s an empty array of a type subclass…
image

Regards, Antoine

Our colleagues will help you from here. :wink:

1 Like