I was writing some code to dynamically load a class the other day, and came up with this little nugget. I can’t seem to find anyone who has done this before, so I’ve dubbed it “Derived Base Class Restriction.” (Note: If someone else has already published this, let me know!)
We’re going to assume the following class hierarchy:
Let’s say I’ve built a framework that uses Abstract Class for some plugin. If I’m writing a particular application for a given customer, I might make Concrete Class 1, and use it as a starting point. I may add descendants, and customers may even add further descendants beyond that.
Typically in my framework, I’d load the plugin something like this:
This is all fine and good, and I can now load any of my descendants. Awesome.
Now, assume Abstract Class is actually intended to do some form of data logging. Concrete Class 1 can send it to a database, Concrete Class 2 can send it to a file. My framework is all fine and good, and let’s the end user point to whatever the appropriate configuration is for their particular use case. BUT…. without changing the framework, there’s no way of enforcing that the user choose a particular branch of the hierarchy. They could log to file when they’re supposed to log to database, or vice-versa.
Here’s my proposal:
The key here is the addition of “preserve run-time class.” For those not familiar, here’s the way I think about it:
To More Specific Class looks at the datatype of the WIRE going to the top input and tries to convert the left input to that type. Technically both Concrete Class 1 and Child of 2 are both more specific versions of Abstract Class. In this case, if they are passed in to the left on a LabVIEW Object wire, they are then put on an Abstract Class wire and move on through.
“Preserve Run-Time Class,” however, is a bit different. It actually evaluates the type of the object on the wire, not just the wire type itself. So, now we find the type of the OBJECT on the top wire and evaluate whether the OBJECT coming in on the left is of that type (or a descendant of that type). If it is of the correct type, then it passes through with no change. If it’s not of the correct type, you get an error.
Using the above and a little imagination, you can now hard code the path to the minimum class in your particular application, without ever actually changing the framework. In most cases I would actually want to do something more like this in my framework:
From my application I could either leave “Abstract Class” unwired (allowing me to load any of it’s descendants) or I could pass in an instance of a descendant, forcing the restriction on the path input (which we would assume the end-user has freedom to choose). No more logging to file when we should be logging to database.
I’m curious to know if anyone has seen this before, or if it seems useful. Leave your thoughts below!