Method, passing a Class name reference as argument

Is there a way to pass a class name as argument in a method

This is the code I want to simplify

// Create Database Tables
CreateTable(db, Folder.TableName + TableRowsDescription(Folder.TableRows, Folder.TablePrimaryKey))
CreateTable(db, Third.TableName + TableRowsDescription(Third.TableRows, Third.TablePrimaryKey))

Folder and Third are 2 classes. They have the same shared method returning TableName, Table Rows and Table primary key

The CreateTable() method is in charge to create the table in the db with some arguments (table names rows, primary key).

I want to simplify my code with something like this

CreateTable(db, Folder)
CreateTable(db, Third)

I don’t know how to make that if there is a way.

If you pass the class name as a string you might be able to do something with introspection.

An alternative would be to use a class interface or superclass, instance methods instead of shared methods and pass an instance of the class.

you can use a class interface for that.
make your 2 classes folder and third belong to the same class interface.
https://documentation.xojo.com/getting_started/object-oriented_programming/interfaces.html

As far as I know, Class Interface provide same methods not same shared methods. I need to access to a shared method

Maybe with introspection but I don’t understand how to implement it to access to a class shared method from the class name as string, any idea ?

I’ve had a quick look and unfortunately, it looks like there are a few pieces of the puzzle missing so this cannot be done.

An Alternative method would be to use a singleton instance in all of the places you supply the class.

Step 1 - Change From Shared Methods To Class Methods
a) Rename the classes Folder & Third (TableFolder / TableThird?)
b) Create a module with public properties Folder & Third which have the correct types
c) During your app initialisation create the class instances and assign them to the Folder & Third properties
d) Switch the shared methods to normal class methods

At this point your code should function the same way as it did before.

Step 2 - Refactor
As long as your table classes have the same superclass or same interface you should be able to refactor the methods so that it accepts the superclass / interface and performs all of the common work.

its somehow

CreateTable(db, Folder.GetData)
CreateTable(db, Third.GetData)

where by GetData could return a common class object.

or

Folder.CreateTable(db)
Third.CreateTable(db)

I’ve been down this road. Yes, it’s possible. Clumsy, but possible. You can use GetTypeInfo to get an introspection object for a class (not an instance) and interrogate that object to find your shared methods.

HOWEVER I strongly recommend not doing this. I ended up refactoring away from this because of random inexplicable problems.

What I was finding is that some users would have no problem using the app, then all of the sudden these classes would act like they didn’t exist. After adding a bunch of logging, it turned out that introspection just couldn’t see the target methods. It’s as if their signatures changed inside a built and signed binary. Nothing would bring the missing methods back except a reinstall. And it would work for a while, then just… not. This only happened to certain users too. It was the strangest thing I’ve ever seen. So I changed how my code worked to not need introspection - which meant an annoying select statement - but the result is much more reliable.

So… don’t do it. I’ve been down that road. Just don’t do it. I know the alternative isn’t exactly elegant, but it works every time, and that is worth far more.

1 Like

Thank you @Thom_McGrath for your feedback. Of course I like elegant code, my first goal is maintainable code but first of all I want robust code without random inexplicable problems.

You could have both classes implement a Class interface if you change the Shared to an instance method (you can still have a shared method or property that contains the actual value, but is returned from the instance method(s)):

  • Add a new Class Interface, name it TableNameProvider
  • Add a Function to The TableNameProvider named “TableName” set String a returnvalue
  • In your “Folder” and “Third” class implement the TableNameProvider interface (just below the super class in the inspector).
  • Now add the code in “Folder” and “Third” that returns the value.
  • In your CreateTable method your param could be TableName As TableNameProvider.

Thank you @DerkJ it’s a good trick but it’s a trick :wink:

1 Like

It’s a solution that may fit you needs or not. Perhaps one other may read it and find it useful some day.

1 Like