From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LVOOP - Casting Weirdness

Solved!
Go to solution

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: 

  • If I use the "To More Specific Class" method to directly cast a child class to a different type, the cast fails (as expected).
  • When I use the "To More Specific Class" method to cast one of my array elements to a different type, the cast *always* succeeds. Why?

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??

 

Casting Weirdness.png

0 Kudos
Message 1 of 8
(3,530 Views)

Hello fabric

Nothing is wrong here. The second cast is cast from Car to Car, so it does nothing in fact. See the picture below.

 

 Classes.png

0 Kudos
Message 2 of 8
(3,522 Views)

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:

  1. Using the "Get LV Class Path" method. (A bit "heavy" for my liking)
  2. Flattening the object to string and parsing the class name. (Good for small classes, but not so nice when the private data gets large)
  3. Writing custom methods for each child class. (Seems crazy for such a basic function!) 
0 Kudos
Message 3 of 8
(3,518 Views)

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):

IsObjectOfClass.png

 

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?

0 Kudos
Message 4 of 8
(3,511 Views)

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:

 SearchByType.png

 

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! Smiley Happy

0 Kudos
Message 5 of 8
(3,509 Views)

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.

0 Kudos
Message 6 of 8
(3,502 Views)

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.

0 Kudos
Message 7 of 8
(3,499 Views)
Solution
Accepted by topic author fabric

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!

0 Kudos
Message 8 of 8
(3,403 Views)