I want to use the serialization framework of Einhugur (http://www.einhugur.com/Html/SerializationFramework/index.html) to transmit classes over sockets. But, when I receive the JSON file at the server side, I want to transform the JSON back in a class. The main problem is that I don’t know what class I received.
I can check the name of the class in JSON, and then create the right class, but that would result in an IF statement for every class I have. I tought it maybe could be done by introspection, but I don’t know how. Any tips on an approach? Maybe with XojoScript?
Create a global dictionary (for example in a module).
Register all possible classes in the dictionary (for example in App.Open):
dct.Value("ClassA") = GetTypeInfo(ClassA)
dct.Value("ClassB") = GetTypeInfo(ClassB)
When you receive the JSON create an instance of the class via introspection:
Dim ti As Introspection.TypeInfo = dct.Value("ClassA")
Dim cis() As Introspection.ConstructorInfo = ti.GetConstructors()
Dim ci As Introspection.ConstructorInfo = cis(0)
Dim myInstance As Object = ci.Invoke()
This is the fancy version of an IF or SELECT CASE statement
In the end there is no “class by name” like there is in something like Java
[quote=191012:@Norman Palardy]This is the fancy version of an IF or SELECT CASE statement
In the end there is no “class by name” like there is in something like Java[/quote]
I don’t see how this is an fancy IF or SELECT statement. This picks the right classname out of a dictionary (or a array) and instances that class. Adding classes is simply done by adding them to the collection of classes. With an if statement this would mean copy pasting elseif statements and would result in a bunch of redundant code, isn’t it?
Norman is right in my opinion:
- You need to list all classes, which is in the end the same work as having an IF or SELECT CASE statement.
- Internally a dictionary is (usually) based on hashing, which can be seen as a very clever IF or SELECT CASE.
Isn’t in the end any program just a whole lot of complex, nested IFs? I once read about the “One instruction set computer”. You need branching or you won’t be able to program anything.
It may still be an IF/SELECT but is a very clean way of registering a lot of classes, especially when making reusable modules.
Still amounts to a handy way to list every possible class you can create which is no better / worse than a long if then else or select case listing them all
In Java’s case the runtime support “ClassByName” without having to register anything and you can construct it simply by having the name
Quite different from whats possible here
Is it worth to do a feature request for that?
I think so yes. Is there anybody that can do that? Thank you
I created a feedback case: <https://xojo.com/issue/39555>
With such a change, it would no longer be possible to strip unused classes from a build, because the compiler could not know which classes were unused.
Add a build option to not strip unused classes for people who want this feature. And/or a per class option for inclusion. Either way if the TypeInfo isn’t found by name return nil.
you can actually already control if a class gets stripped or not
I think, for now, a declaration that uses it will do
dim t as classNotToStrip
Not sure if this will continue to work or not with LLVM as its much better about figuring out what code can be stripped and whats unused etc
Assuming the code is reachable and not itself stripped out, there’s two guaranteed ways to make a class not be entirely stripped: New and GetTypeInfo. Even this is a bit of an implementation detail because there’s no way in the program to observe whether or not it’s been stripped out.
It’d only be a minor convenience to have a GetTypeInfo(“name”) built in, along with IDE control over including classes.
Making your own GetTypeInfo(“name”) and maintaining a master method where all the lookupable classes are listed isn’t that much trouble.
Although, private classes in a module can’t easily be added. Listing spreads out, there’s no longer a single master method to maintain and it gets clumsy.
It could also be an option just to make the strip unused classes function better. Let it search the forName(); function and mark the class as used.
One thing I noticed when I moved from RB to Xojo was that the linker did a worse job at stripping things out. For example:
- If I define a property that refers to a plug-in class, Xojo will include the plug-in while RB will strip it (FB33072).
- If I define dynamic strings which are not referenced in code, Xojo will include them while RB will strip them (FB33070).
The change could have been before Xojo as we jumped from quite an old version of RB to Xojo but it was a bit of a surprise.
But it’s possible that the name passed to this forName function cannot be determined at compile-time.
How old a version of REALbasic? These haven’t changed as long as I’ve been working here.
And if it could be resolved at compile time, why not just use GetTypeInfo.