B4J Question Is testing type in Select case possible?

knutf

Active Member
Licensed User
Longtime User
This code works

B4X:
Sub Process_Globals
    Type t1(memberX As String)
    Type t2(memberY As String)
End Sub

Sub AppStart (Args() As String)
    Dim vt1 As t1
    Dim vt2 As t2
    
    LogType(vt1)
    LogType(vt2)
End Sub

Sub LogType(o As Object)
    If o Is t1 Then
        Log("t1")
    else if o Is t2 Then
        Log("t2")
    End If   
End Sub

But is it possible to do the same with "Select case" instead of "If Then else"?
 

MarkusR

Well-Known Member
Licensed User
Longtime User
something like this?
B4X:
    Select True
        Case o Is t1
            Log("t1")
        Case o Is t2
            Log("t2")
    End Select
 
Upvote 0

knutf

Active Member
Licensed User
Longtime User
Yes, but in my opinion this is less intuitive than
B4X:
If o Is t1 Then
    Log("t1")
else if o Is t2 Then
    Log("t2")
End If

I would love this:
B4X:
Select o
        Case Is t1
            Log("t1")
        Case Is t2
            Log("t2")
End Select

But it is not allowed
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
I would love this
yes
But it is not allowed
i think the compiler can not understand, u must make a feature request.

maybe its better to work with classes that each of them have methods for debugging.
a.MyLog
is better than MyLog(a)
because after dot you get a pick list of available methods.
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
How about this as a solution (bit hacky but simple)
B4X:
Sub Process_Globals
 Type t1(memberX As String)
 Type t2(memberY As String)
End Sub
Sub AppStart (Args() As String)
 Dim vt1 As t1
 Dim vt2 As t2
    
 xLogType(vt1)
 xLogType(vt2)
 'StartMessageLoop
End Sub
Sub xLogType(o As Object)
 Select GetType(o)
  Case isType("t1")
   Log("its t1")
  Case isType("t2")
   Log("its t2")
  Case Else
   Log("unknown") 
 End Select
End Sub
Sub isType(s As String) As String ' the name of the class of type t1 t2 etc MUST be in this module in globals
 Dim ret As String = Me ' get this class name
 Return ret.Replace("class ","")&"$_"&s  ' add the type class name  eg  b4j.example.main$_typeclass 
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
 Return True
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Or even:

B4X:
Sub Process_Globals

    Type T1(memberX As String)
    Type T2(memberY As String)
    Dim T1Type As String
    Dim T2Type As String
End Sub

Sub AppStart (Args() As String)
    Dim T1Ref As T1
    Dim T2Ref As T2
    T1Ref.Initialize
    T2Ref.Initialize
    T1Type = GetType(T1Ref)
    T2Type = GetType(T2Ref)
   
    Dim vt1 As T1
    Dim vt2 As T2
   
    xLogType(vt1)
    xLogType(vt2)
   
End Sub
Sub xLogType(o As Object)
    Select GetType (O)
        Case T1Type
            Log("Is T1")
        Case T2Type
            Log("Is T2")
        Case Else
            Log ("Unknown")
    End Select
End Sub
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
or
B4X:
Sub LogType(o As Object)
   
    Dim t1 As t1
    Dim t2 As t2
           
    Select GetType(o)
        Case GetType(t1)
            Log("t1")
        Case GetType(t2)
            Log("t2")
    End Select
   
End Sub

but my Select True was the prettiest
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
As regard the alternate solutions, for a few types its fine, but if there were 50+ types, you would add lots of extra lines to the code.
(that came out sounding wrong, I mean for a few types then I like your methods)
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
but my Select True was the prettiest

Yes, but in this case you are testing the type of the reference variables for every test, that takes additional time.

Also something to consider is that if you are testing a lot of object types, an If Then tree would be much quicker again.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
The select gets changed anyways in my example (wonder who 10/10 for the code Erel )
B4X:
  public static String _xlogtype(Object paramObject)
    throws Exception
  {
    switch (BA.switchObjectToInt(Common.GetType(paramObject), new Object[] { _istype("t1"), _istype("t2") }))
    {
    case 0:
      Common.Log("its t1");
      break;
    case 1:
      Common.Log("its t2");
      break;
    default:
      Common.Log("unknown");
    }
    return "";
  }
 
Upvote 0

knutf

Active Member
Licensed User
Longtime User
My wish is to make the code as readable as possible.

How about this as a solution (bit hacky but simple)

I think the select - case part of your suggestions is pretty readable, but the cost is the extra code that make the complete code less readable, and it takes a lot more time to code. Then it is still better with:

B4X:
If o Is t1 Then
    Log("t1")
else if o Is t2 Then
    Log("t2")
End If

- it is faster to code and still more readable than your suggestions.

I think I ....
must make a feature request.
 
Upvote 0

knutf

Active Member
Licensed User
Longtime User
Your post arrives while I'm writing (or slowly spelling my english). Your creative suggestions proves to me that a language support for typetesting in select - case blocks would be well received.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…