08-10-2012 11:16 PM
I have discovered some strange behaviour of the "To More Specific Class" method... I'm using LV2011SP1.
My application:
I have an application that analyses a collection of data blobs, with each data blob defined by a LV class. Each of these data blobs inherits from a common parent. I store my data blob collection as an array. Standard stuff.
Obviously each data blob needs to be upcast to the parent type when stored in an array, but the runtime value of each array element is retained as the correct child data type.
There is part of the analysis where I need to do some type checking for some of the blobs, so I use the "To More Specific Class" primitive to attempt to cast elements of my array to the desired data type. A mismatch between the input type and the target type should produce an error, right?
Here's the weird part:
The image below illustrates the issue. Ferrari and Mini are both children of Car. Casting Mini to Ferrari gives an error (as expected), but casting Mini to an upcasted version of Ferrari works! This seems odd to me given that the runtime value of the target type is "Ferrari" (as shown by the probe).
So why does the "To More Specific Class" method not use the runtime values of its inputs??
Solved! Go to Solution.
08-11-2012 04:32 AM
08-11-2012 05:10 AM
Hi PiDi - thanks for the reply.
I understand what you are saying, but the essence of my question is why the *runtime* value is not used on the "target" input of the second cast... For example, if I route that wire into a dynamic dispatch method then the appropriate child method is executed, not that of the parent.
The bigger question is how best to do type checking when the source objects have been upcast? Three methods I use are:
08-11-2012 06:11 AM
To More Specific Class determines type to which it casts at "compile" time, not at runtime. It will always try to cast to exact class you've connected to "target class" input. It couldn't work the way you say (determine target class at runtime) - because of ambigouity and counter-intuitiveness.
If you want to check whether given object is of given class, you can use a simple snippet (Class and Object inputs are of LabVIEW Object type):
However, there is no way to determine that your object has been "upcasted" to parent class. The fact is that no object is ever physically upcasted, because it is always the object of the parent class. In my example, Green and Red are always of Color class (and of LabVIEW Object class), so checking against Color class will always be successfull. The question is: why do you need to check if object was upcasted?
08-11-2012 06:57 AM
I don't specifically need to check if my object was upcasted. Rather, a collection of objects have been upcasted so they can be passed around as an array, and I later need to search that array for the first matching type.
I was attempting to write a generic "Search By Type" method that would scan that array and check type using the "To More Specific Class" node:
The problem with this is that any such generic method relies on upcasted inputs, hence the cast always succeeds (as per my original post).
If I replace "target data" with a class constant of the desired type then the function works fine, but that's not very generic!
Anyway, it seems as though I may need to customise the type check for each of my (many) analysis functions.
It couldn't work the way you say (determine target class at runtime) - because of ambigouity and counter-intuitiveness.
I'm not sure I agree that such behaviour would be ambiguous. I'm actually quite surprised that it doesn't use the runtime value! (Can anyone from NI suggest why it works this way??) As you mention, a LVOOP class is never really upcasted. The wire may resemble the parent class, but the payload is defintely the child...
Thanks for your contributions all the same!
08-11-2012 10:31 AM
fabric wrote:
I was attempting to write a generic "Search By Type" method that would scan that array and check type using the "To More Specific Class" node:
If you find yourself doing operations like this then this operation should be part of the class you are defining, thus allowing you to simply call a dynamic dispatch VI. You should normally never need to "To more specific class". You can also implement a simply "Get Type" method which returns a string identifying the RUN-TIME type of the object.
Shane.
08-11-2012 11:55 AM
In addition you can pass the required type to the class and ask the class if it's of the same type.
Remember, OOP is in part about telling classes what to do, not asking for class data and doing things yourself. Say that several times out loud and then re-think your "problem".
Shane.
10-05-2012 12:38 AM
Just a quick follow up...
I found all my answers in this post over at LAVA: http://lavag.org/topic/16081-am-i-understanding-the-reason-why-i-have-to-use-preserve-rt-class-corre...
It seems that the "Preserve Run-time Class" function does exactly what I need, i.e. it performs its type checking based on the run-time value of the reference class input. By contrast, the "To More Specific Class" function is very similar but does its type checking at edit-time.
Useful information, but not so clear from the help page!