Hi all,
It seems that Ax has two different root base classes: object and some kind of "internalobject"
I've always used some kind of calls like SysDictClass::isEqualOrSuperclass(classIdGet(obj), classNum(Object)) to distinguish between these different kind of inheritance hives.
Starting with Ax2012 the is operator can be used for inheritance checks. But it seems to be not possible, due to the lack of a missing InternalObject class, to use this for check if a passed class instance (derived from object or derived from "nothing")
The result of a call like if (instantiatedObjectVar is Object) seems to deliver true in all cases.
So I can use only the old construct if (! SysDictClass::isEqualOrSuperclass(classIdGet(obj), classNum(Object)) to check for a 'non-object ' object?
Is this a bug or is this the intended design?
Example:
public class MyChildFromInternalRoot
public class MyChildFromObject extends object
public static void checkTest(object obj) // some static method e.g. in MyTools Class
{
boolean b1;
str s1;
boolean bOK1;
boolean bOK2;
;
if (obj != null)
{
bOK1 = obj is Object;
bOK2 = SysDictClass::isEqualOrSuperclass(classIdGet(obj), classNum(Object));
info(strFmt('isObject: %1 %2',bOK1, bOK2));
s1 = obj.toString();
b1 = obj.objectOnServer();
}
}
MyChildFromInternalRoot obj1 = new MyChildFromInternalRoot();
MyChildFromObject obj2 = new MyChildFromObject();
;
MyTools::checkTest(obj2);
MyTools::checkTest(ob1);
regards Douglas
*This post is locked for comments
Note that Common Language Specification requires all classes to extend from a CLS-compliant class (System.Object is CLS-compliant). If X++ becomes a ".NET language" in AX 7, everything will directly or indirectly inherits from System.Object and the problem will disappear.
I believe that this is going to happen.
Hi Martin,
many many thanks for this information. So it seems to be really intended.
Hopefully the other was (using ax reflection with DictClass) won't be discontinued in further versions or releases. Otherwise you will not have any chance to detect these curious class instances to avoid the calls of non-existing methods.
regards
Douglas
There surely is a difference whether you use extends Object or not. It indeed is weird behaviour and never made good sense to me (I'm aware of it since AX 3.0).
In some places, Microsoft call it explicit (with extends) and impllicit (without extends) inheritance from Object. Nevertheless it seems to me that there is no root class as in other languages - Object is just a class as any other that you can use to inherit some common methods. This isn't true for CIL generated from X++. of course - Object has a special meaning there. The is operator seems to be intentionally written in a way that returns the same result both both in X++ and CIL from X++.
Hi,
but there seems to be a object oriented hierarchy paradoxon withion Ax.
There exists TWO base classes and only one of them can be "named"
so NOT any object instance is an object, maybe it's from the other hive.
So for me the question makes sense !!!!
In all other oject oriented languages it doesn't make sense. But then I would not ask.
so sorry for my "foolish" question.
regards
Douglas
JHi,
Sorry but there are a lot of classes which do not derive from object, but from some kind of "masterbaserootobject" or something else.
It depends on the class declaration only.
The Problem is: All explicit from object derived (classdeclaration extends object) for example have a method toString() or objectOnServer()
If I have a generic Method to which can pass ANY object instance (derived from object or derived from "internalroot")
I can for example only call the toString() method if this is an explicit extends objects derived class.
For this case I'd always used (in many cases) the SysDictClass::IsEqualOrSuperClass call.
This works like a charme. So I can skip object instances which are not derived from object.
regards Douglas
I'm agreeing with Martin here. You're actually passing in the variable as an object, so obviously it IS an object. I'm not sure what you're going for.
The only "somewhat objects" that don't derive from Object are Tables and CLRObjects - and those will return false with the IS operator.
Are you looking to use "anytype" and then check for typeof() which returns the Types:: enum?
That (instantiatedObjectVar is Object) returns true for all objects makes very good sense to me. Don't you think the same?
What situation are you trying to handle?
André Arnaud de Cal...
291,965
Super User 2025 Season 1
Martin Dráb
230,817
Most Valuable Professional
nmaenpaa
101,156