I was working a bit on the 'ambiguous match'-thing for properties and ran into a weird thing using CAST, where I couldn't cast from a subclass to its super, both being quite vanilla. The problematic line is this from InvocationResult.cpp
if (oldType->IsAssignableFrom(newType)) {
I'm pretty sure this is supposed to be
if (newType->IsAssignableFrom(oldType)) {
This fixes the case I had problems with, but ufortunately reveals another problem in the Excel example, where now this no longer works:
(cast [get_Item worksheets 1] "Worksheet")
The object returned is a com-object returned as a System.Object, and the cast fails with "object must implement IConvertible". It's possible to cast the worksheet to System.__ComObject, but that doesn't help. This seemed to work earlier only because the first test was inverted, thus returning true in this case and forcing the container-type to the correct value. I'll try to find the source of this.
The 'fix' for the ambiguos-match-thing, by the way, tries to simulate what C# does by searching the base classes of the object queried when the exception occured, thus letting one retrieve the 'other' property by casting to the appropriate superclass. That is, if one has classes A, B and C, with A > B > C, and A and B each defining a property with different return-type, then (property C) will return the one defined in B, whereas (property (cast C A)) will return the one defined in A. And that is how I found the issue with CAST.
I put 'fix' in quotes because this is obviously not really neccessarily how things should work; C# is one thing but the .Net methods would more naturally just take the desired return-type as an argument where the property is ambiguous. But I think perhaps this is more intuitive (given C#'s behaviour), syntactically simpler, and also it seemed like good excercise.
Regards, Iver
The object returned is a com-object returned as a System.Object, and the cast fails with "object must implement IConvertible". It's possible to cast the worksheet to System.__ComObject, but that doesn't help. This seemed to work earlier only because the first test was inverted, thus returning true in this case and forcing the container-type to the correct value. I'll try to find the source of this.
Very preliminary searching seems to indicate that System.__ComObjects have a 'real type' one has to somehow get to, and that this has to be handled especially by applications lucky enough to recieve them.
Very preliminary searching seems to indicate that System.__ComObjects have a 'real type' one has to somehow get to, and that this has to be handled especially by applications lucky enough to recieve them.
Some more reading, and it appears that __ComObjects doesn't really have a "real" type, but rather implements a set of interfaces one has to query the old way.
Approximating this using Marshal:IsComObject and simply assuming the user knows what he is doing, I found that the excel example still wouldn't work because excel cheerfully also returns a non-COM object - an array - as a System.Object. The 'real' type of the object is available, and changing oldType to be container->getContainerObject()->GetType(); makes the excel example work again, but I wonder if it wouldn't be easier to just add something like UNSAFE-CAST or FORCE-CAST or something for working with Interop and similar situations. I'll fix it somehow anyway.
Accessing properties of COM-objects (without using the get_-methods) is also sketchy; but I don't think this could reasonably be called RDNZL's fault.
Regards, Iver