Is it possible to test if two types are of the same unknown inheritance in VB.net? - vb.net

Is it possible to dynamically identify the closest common hierarchy or inheritance of two or more unknown typed objects? In other words, I'd like to test if, say, Integer and String have a common hierarchy, without knowing the objects I'm testing are going to be an Integer and String due to user selection. I found a C++ question posted that seems similar to my issue here: Check if two types are of the same template
However, I'm not familiar with any VB.net equivalents of the answers posted there, and online translators simply provide an error when I attempt to translate them. So is this even possible in VB.net in the first place?
The closest to this action that I know of is the .IsAssignableFrom() function, but in my case I don't know what the parent class/interface/whatever is to test against in the first place. the above function is the only thing even remotely related to this issue that pops up on any search I do.
The context I need this is in the Revit API; I'm trying to see if user selected elements have a similar hierarchy/inheritance that is not the Object Type, and if so to allow an action, otherwise, give a warning dialog box.
EDIT: Due to the nature of the Revit API and the desired effects of my command, the users of my plugin could select anything in the model, and I'm not able to determine which of the MANY common ancestors I could be looking for to compare using IsAssignableFrom. I could test for the (I think universal) common ancestor of Element type, but I don't want to allow users to run the command if you select a wall and an element tag. I need to find the common ancestors of the user-selected elements and confirm that the closest common ancestor is below Element type in hierarchy.
For example, the room tag element in the API has a hierarchy sort of like this:
Object -> Element -> SpatialElementTag -> RoomTag
There may be more intermediate inheritances, but I'm not going to track them down in the API documentation. And then each element may have a slightly different ancestry. IsAssignableFrom would be great if I knew the base ancestry I wanted to test for.
TnTinMn's answer gives me the type of solution I'm looking for.

The Type.BaseType Property returns:
The Type from which the current Type directly inherits, or null if the current Type represents the Object class or an interface.
Using this information, it is possible to define an iterator to enumerate the inheritance tree.
Private Iterator Function SelfAndAncestors(srcType As Type) As IEnumerable(Of Type)
Do Until srcType Is Nothing
Yield srcType
srcType = srcType.BaseType
Loop
End Function
Now you can use the Enumerable.Intersect Method to find all common types in the inheritance between two ancestry enumerations and return the first common ancestry type.
Dim t1 As Type = GetType(Form)
Dim t2 As Type = GetType(UserControl)
Dim highestCommonAncestor As Type = Enumerable.Intersect(SelfAndAncestors(t1), SelfAndAncestors(t2)).First()
For this case, the highest common ancestor is ContainerControl.

Related

How to call remove_column on SALV table?

I want to execute the method remove_column on an instance of cl_salv_column_table but because of its visibility level, I am not able to do so.
Plan:
I already tried inheriting from cl_salv_columns_list and then perform the call inside the remove-method:
CLASS lcl_columns_list DEFINITION INHERITING FROM CL_SALV_COLUMNS_LIST.
PUBLIC SECTION.
METHODS:
remove IMPORTING iw_colname TYPE string.
ENDCLASS.
But apparently my casting knowledge got rusty as I'm not able to figure out an appropriate solution.
This is my current hierarchy - the red arrows show the way I would have to take:
My approach looks like this:
DATA lo_column_list TYPE REF TO lcl_columns_list.
lo_column_list ?= CAST cl_salv_columns_list( lo_columns ).
But it fails with:
CX_SY_MOVE_CAST_ERROR
Source type: \CLASS=CL_SALV_COLUMNS_TABLE
Target type: "\PROGRAM=XXX\CLASS=LCL_COLUMNS_LIST"
Background:
My task is to select all columns of 3 tables (which would be done like SELECT t1~*, t2~*, t3~* ...) as long as their names don't conflict (e.g. field MANDT should only be displayed once). This would require defining a very big structure and kick the size of the selection list to a maximum.
To avoid this, I wanted to make use of the type generated by my inline-declaration. Hiding the individual columns via set_visible( abap_false ) would still display them in the layout manager - which looks really ugly.
Is there any other way to accomplish my target?
Use set_technical( abap_true ) to hide the columns entirely. As for your approach - sorry, inheritance does not work that way - in no statically typed object oriented language that I know. You can't 'recast' an instantiated object to a different class. You would need to modify the framework extensively to support that.

How reliable is it to use abs_x / abs_y or x/y(relative) for WebElement recognition with QTP/UFT?

I am trying to write a function to recognize a webelement which has following identification properties:
class
innertext
innerHTML
abs_x and abs_y
x and y (relative)
Issue is, the value for "class" keeps changing with different application updates so it can't be used for recognition.
Now, I have option to use absx/absy or x/y.
I believe x/y would be better.
How reliable is it?
No way!! You should not use any coordinates as properties to find an element!!
It will not be reliable at all. Also, if you to try to run the script in another machine with different resolution, it might not work as well.
Go with 'innertext' & class name. If the class name keeps changing, does it have any pattern like class1, class2 ..etc. if yes, you can use Regular Expression. Worst case, you can use Ordinal identifiers.
I would never consider coordinates in my test!!
If possible avoid using coordinates for identification since this is very brittle (may break the test for any minor change). Obviously abs_x is worse than x since it depends on the browser's location in addition to the elements location in the page.
I would inspect the element to see if there are any properties that identify it consistently, it could be something other than the properties you listed (e.g. title, role), if possible use that rather than the location.
Actually, it is not true at all that use of coordinates abs_x and abs_y are always unreliable!! Hard coding them is always unreliable, but properly using them dynamically is 100% reliable.
Take the case where the only way to identify an object is by it's location in relation to another object that can be identified. Using the Object Repository, this is accomplished using the built in "Visual relationship identifier". The implementation of this same capability - visual relationship idenfication - in programmatic descriptions is accomplished using abs_x and/or abs_y coordinates.
For example, if you have an identifiable object whose abs_y value is the same as the unidentifiable object (i.e., they are consistently on the same horizontal axis or on the same axis plus or minus some number), locate the object which can be identified in the normal manner and using GetROProperty, get it's abs_y coordinate. Then, locate the other object that otherwise cannot be located, using the value of abs_y just gotten. That is, the abs_y coordinate of the identifiable object will be the abs_y value of the object that otherwise cannot be identified. Again, this is exactly what the built in Object Repository capability of "Visual relationship identifier".
Example:
sAbsY = Browser(...).Page(...).WebElement(...).GetROProperty("abs_y")
Browser(...).Page(...).WebElement(..., "abs_y:=" & sAbsY).Click

Frege: can I derive "Show" for a recursive type?

I'm trying to implement the classical tree structure in frege, which works nicely as long as I don't use "derive":
data Tree a = Node a (Tree a) (Tree a)
| Empty
derive Show Tree
gives me
realworld/chapter3/E_Recursive_Types.fr:7: kind error,
type constructor `Tree` has kind *->*, expected was *
Is this not supported or do I have to declare it differently?
Welcome to the world of type kinds!
You must give the full type of the items you want to show. Tree is not a type (kind *), but something that needs a type parameter to become one (kind * -> *).
Try
derive Show (Tree a)
Note that this is shorthand for
derive Show (Show a => Tree a)
which resembles the fact that, to show a tree, you need to also know how to show the values in the tree (at least, the code generated by derive will need to know this - of course, one could write an instance manually that prints just the shape of the tree and so would not need it).
Generally, the kind needed in instances for every type class is fixed. The error message tells you that you need kind * for Show.
EDIT: eliminate another possible misconception
Note that this has nothing to do with your type being recursive. Let's take, for example, the definition of optional values:
data Maybe a = Nothing | Just a
This type is not recursive, and yet we still cannot say:
derive Show Maybe -- same kind error as above!!
But, given the following type class:
class ListSource c -- things we can make a list from
toList :: c a -> [a]
we need say:
instance ListSource Maybe where
toList (Just x) = [x]
toList Nothing = []
(instanceand derive are equivalent for the sake of this discussion, both make instances, the difference being that derive generates the instance functions automatically for certain type classes.)
It is, admittedly, not obvious why it is this way in one case and differntly in the other. The key is, in every case the type of the class operation we want to use. For example, in class Show we have:
class Show s where
show :: s -> String
Now, we see that the so called class type variable s (which represents any future instantiated type expression) appears on its own on the left of the function array. This, of course, indicates that s must be a plain type (kind *), because we pass a value to show and every value has per definition a type of kind *. We can have values of types Int or Maybe Int or Tree String, but no value ever has a type Maybe or Tree.
On the other hand, in the definition of ListSource, the class type variable c is applied to some other type variable a in the type of toList, which also appears as list element type. From the latter, we can conclude, that a has kind * (because list elements are values). We know, that the type to the left and to the right of a function arrow must have kind * also, since functions take and return values. Therefore, c a has kind *. Thus, c alone is something that, when applied to a type of kind * yields a type of kind *. This is written * -> *.
This means, in plain english, when we want to make an instance for ListSource we need the type constructor of some "container" type that is parameterized with another type. Tree and Maybe would be possible here, but not Int.

Finding variables that share common properties

I'm using Mathematica and have a set of variables (A,B,C,D,...) with properties A=(blue, big, rounded), B=(red, small, spiky), and so forth. Those properties can be common between variables. What would be the best, general way to find all variables that share a common property (of being, for instance, small)? Thanks.
Here's a list of possible properties:
In[1]:= properties={"red","green","blue","big","small","rounded","spiky"};
And here's a list of objects with some of those properties
In[2]:= list={{"blue","big","rounded"},{"red","small","spiky"},
{"red","big","rounded"},{"blue","small","spiky"}};
You can find all objects that have the property of, e.g., being "blue" using Select
In[3]:= Select[list, MemberQ[#,"blue"]&]
Out[3]= {{blue,big,rounded},{blue,small,spiky}}
This could be wrapped up into a function. Although how I would write that function would depend on the data structures and usage that you're planning.
Actually, I just reread you question you have a list of objects with some properties and you want to refer to those objects by name. So you probably want something more like
In[1]:= listProperties["A"]:={"blue","big","rounded"}
listProperties["B"]:={"red","small","spiky"}
listProperties["C"]:={"red","big","rounded"}
listProperties["D"]:={"blue","small","spiky"}
Above I defined some properties that are associated with certain strings. You don't have to use strings in the above or below, and you can create a better structure than that if you want. You could also make a constructor to create the above, such a constructor could also check if the list of properties supplied is of the right form - i.e. does not have contradictory properties, are all in a list of known properties etc...
We then define a function to test if an object/string has a certain property associated with it
In[2]:= hasProperty[obj_, property_]:=MemberQ[listProperties[obj],property]
You might want to return an error or warning message if listProperties[obj] does not have a definition/rule associated with it.
Use Select to find all "objects" in a list that have the associated property "blue":
In[3]:= Select[{"A","B","C","D"}, hasProperty[#,"blue"]&]
Out[3]= {A,D}
There are other ways (probably better ways) to set up such a data structure. But this is one of the simplest ways in Mathematica.

How to get differing value type out of an concrete implementation if only Interface / abstract class is known?

what I am using:
VB.NET, NET 3.5, OpenXML SDK 2.0
what I want to do:
I am creating an xlsx reader / writer for my application (based on OpenXML SDK 2.0). I want to read xlsx files and store the data contained in each row in a DTO/PONO. Further I want to read the xlsx file and then modify it and save it.
my thoughts:
Now my problem is not with the OpenXML SDK, I can do what I need to do.
My problem is on how to structure my components. Specifically I have problems with the polymorphism at the lowest level of a Spreadsheet, the cell.
A cell in Excel/OpenXML can have different types of data associated with it. Like a Time, Date, Number, Text or Formula. These different type need to be handled differently when read/written from/to a spreadsheet.
I decided to have a common interface for all subtypes like TextCell, NumberCell, DateCell etc.
Now when I read the cell from the spreadsheet the Method/Factory can decide which type of cell to create.
Now because the cell is an abstract from the real implementation it does not know / does not need to know of what type it is. For writing / modifying the cell I solve this problem by calling .write(ICellWriter) on the cell I want to persist. As the cell itself knows what type of data it contains, it knows which method of ICellWriter it needs to call (static polymorpism).
My problem:
Writing to the xlsx file is no problem. My problem is, how do I get the data out of my cell into my DTO/PONO without resorting to type checking -> If TypeOf variable is ClassX then doesomething End If. As Methods / Properties have to have different Signatures and differentiating by only using a different return type is not allowed.
Edit:
The holder (collection, in this case a row of a table/spreadsheet) of the objects (refering to the cells) does not know the concrete implementations. So for writing a cell I pass it a Cellwriter. This Cellwriter has overloaded methods like Write(num as Integer), Write(text as String), Write(datum as Date). The cell object that gets this passed to it then calls the Write() method with the data type it holds. This works, as no return value is passed back.
But what do I do when I need the concrete data type returned?
Any ideas, advice, insight?
Thanks
Edit:
Glossary:
DTO: Data Transfere Object
PONO: Plain Old .Net Object
xlsx: referring to file ending of excel workbook files
Edit:
The Cell "subtypes" implement a common interface and do not inherit from a common superclass.
Edit:
After some thinking about the problem I came to realize that it’s not possible without reflection or knowledge of what type of cell I am expecting. Basically I was trying to recreate a spreadsheet or something with similar functionality and way too abstract/configurable for my needs. Thanks for your time & effort put in to writing the answer. I accepted the answer that was closest to what I realized.
I don't think you can.
If I'm understanding correctly, you have a different types of cells (StringCell, IntCell) and each of those concrete classes returns an object of type 'Object'. When you are using the base class 'Cell' and getting it's value - it's of type Object.
To work with it as a String, or Integer, Or Date, etc...etc... I think you need to inspect the type of that object, one way or another. You can use TypeOf like you demonstrated; I've also seen things like '.GetValueAsString()/.GetValueAsInteger()' on the base class. But you still need knowledge enough to say 'Dim myInt as Integer = myCell.GetValueAsInteger()'
Generally speaking, at least if you subscribe to the SOLID principals, you shouldn't care.
It states that, in a computer program if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substitutes for objects of type T), without altering any of the desirable properties of that program (correctness, task performed, etc.)
http://en.wikipedia.org/wiki/Liskov_substitution_principle
If you have subtypes of cells, but you can't use them interchangeably, it's a good candidate for not using inheritance.
I don't know what you intending to do with the values in the cells that would require you to have the concrete class instead of using the base; but it might be possible to expose that functionality in the base itself. IE - if you need to add two cells, you can accomplish that treating them as generic cells (perhaps. At least provided they are of compatible types) without knowing what subtype they are. You should be able to return the base class in your DTO, regardless.
At least, I that's my understanding. I'd certainly wait for more people to chime in before listening to me.