Is it possible to get names and types of a custom type?
B4X:
Type tPerson(Name As String, Surname As String, Age As Int)
' Something like:
'... GetTypeNumOfFields(tPerson)
'... GetTypeFieldName(tPerson, 0) ' <--- 0 = index of first field
'... GetTypeFieldType(tPerson, 0) ' <--- 0 = index of first field
Searching, I "found" that Java does not have "Structures" - like C#-VB Net Struct-Structure "types".
So I suppose the B4X "custom type" is something specially created by Anywhere Software and maybe it's possible that it could expose what I asked for (adding this rarely used feature, I'm afraid).
It's pretty trivial. I've tested this with jReflection in B4J but it should work in BA (touch wood!)
B4X:
Dim tp As tPerson
tp.Initialize
Dim o1, o2 As Reflector
Dim oa(0) As Object
Dim str As String = ""
o1.Target = tp
o2.Target = o1.RunMethod("getClass")
oa = o2.RunMethod("getFields")
For i = 0 To oa.Length - 1
Dim str1 As String = oa(i)
Dim idx As Int = str1.LastIndexOf(".")
str = str & str1.SubString(idx+1) & ", "
Next
fx.Msgbox(MainForm, str, "")
A bit more code would give the type for each field if you wanted it.
Is this function enough/correct to check if an object is of a custom type declared in the Main module?
B4X:
Public Sub IsCustomTypeInMain(ObjectToCheck As Object) As Boolean
Dim Refl1, Refl2 As Reflector
Dim Objects(0) As Object
Refl1.Target = ObjectToCheck
Refl2.Target = Refl1.RunMethod("getClass")
Objects = Refl2.RunMethod("getFields")
Dim str As String = Objects(0)
Return (str.StartsWith("public boolean b4j.example.main$_"))
End Sub
Um... maybe but only in b4j.
P.S. ... and only if the package name was "b4j.example"!
Public Sub IsCustomTypeInMain(ObjectToCheck As Object) As Boolean
Dim joBA As JavaObject
joBA.InitializeStatic("anywheresoftware.b4a.BA")
Dim PackageName As String = joBA.GetField("packageName")
Dim Refl1, Refl2 As Reflector
Dim Objects(0) As Object
Refl1.Target = ObjectToCheck
Refl2.Target = Refl1.RunMethod("getClass")
Objects = Refl2.RunMethod("getFields")
Dim str As String = Objects(0)
Return (str.StartsWith($"public boolean ${PackageName}.main$_"$))
End Sub
Probably not. That will not be a unique class prefix.
Objects(0) in your example will be the IsInitialized Boolean field so you would be better checking for that explicit name and type but it might also occur in other objects.
If you are looking only to identify custom types from your application then why not just add a 'CustomType' field to the type declaration. You don't need to assign anything to it. You can then check for the presence of this field name.
B4X:
Type tPerson(CustomType As Boolean, Name As String, Surname As String, Age As Int)
Or you could use a unique prefix to the type and check for that at the beginning of the class name.
B4X:
Type MytypePerson(Name As String, Surname As String, Age As Int)
Objects(0) in your example will be the IsInitialized Boolean field so you would be better checking for that explicit name and type but it might also occur in other objects.