• TypeId浅析


    AX提供了一些内置函数用来获取数据的类型,比如Typeof(),比如ClassIdGet(),TypeId().
    这里只讨论一下TypeId(),查了半天都没找到关于这个函数的描述,倒是Inside AX这本书对TypeOf()有所描述:
    Typeof()这个系统函数以变量实例为入参,返回入参对应的基本类型,比如下面的例子:
    int i = 123;
    str s 
    = "Hello world";
    MyClass c;
    Guid g 
    = newGuid();

    print typeOf(i); 
    //Prints Integer
    print typeOf(s); //Prints String
    print typeOf(c); //Prints Class
    print typeOf(g); //Prints Guid
    pause;
    它的返回值是Types这个系统枚举类型的一个值,该枚举类型为X++中所有的基本类型包含一个值。当然我们可以用如下方法打印出Types这个系统枚举类型对应的值。
    static void Types(Args _args)
    {
        DictEnum    dictEnum 
    = new DictEnum(enumNum(Types));
        
    int i;
        ;
        
    for(i=0;i<dictEnum.values();i++)
        
    {
            info(int2str(dictEnum.index2Value(i)));
            info(dictEnum.index2Label(i));
        }


    }
    接下来再看TypeId这个函数,在Global这个类中我们可以看到有如下方法:
    /*
        Returns a valid Extended Data Type Id, given the argument in the form the system function typeId returns
    */

    static extendedTypeId typeId2ExtendedTypeId(int _extendedType)
    {
        
    if ((_extendedType & 0xffff!= Types::UserType)
            
    throw error(strfmt("@SYS26445",funcname()));

        
    return _extendedType >> 16 & 0xffff;
    }
    当然还有个类似的方法:
    /*
        Returns a valid Enum Id, given the argument in the form the system function typeId returns.
        Consider use the enumNum intrinsic function, instead of this function!
    */

    static enumId typeId2EnumId(enumId _enumId)
    {
        
    if ((_enumId & 0xffff!= Types::Enum)
            
    throw error(strfmt("@SYS23815",funcname()));

        
    return _enumId >> 16 & 0xffff;
    }

    从函数说明可以看出,这两个方法的入参都是函数TypeId()的返回值。我试了一下TypeId()这个方法的入参只能是EDT或者Enum类型(当然由于没有看到相关的文档,只是我测试的结果,可能不准确),其他类型做入参的时候就报错说:
    *** 错误: 97,FunctionModuleID 的参数不是模块。
    从上面的两个函数我们就可以推测出typeId()这个函数的返回值是什么了。
     if ((_extendedType & 0xffff!= Types::UserType)
            
    throw error(strfmt("@SYS26445",funcname()));
    typeId()函数的返回值与0xffff做按位与运算显然是要屏蔽其返回值的高16位,从而取得低16位,而与运算的结果与Types类型做比较,显然其低16位对应的是EDT类型(或者枚举类型)对应的原始类型,当然枚举类型对应的是Types::Enum,EDT类型对应的是Types::UserType.
    return _extendedType >> 16 & 0xffff;
    右移16位,然后跟0xffff按位与,返回的是EDT类型(或者枚举类型)的ID,那显然typeId()方法返回值的高16位对应的是EDT类型(或者枚举类型)的ID了。
    猜想的话,这些信息应该存在了AOD文件里,typeId()这个函数取得了该信息。
    如果用typeId来取得EDT类型的Id,代码应该类似下面代码的样子:
    typeId2ExtendedTypeId(typeId(AccountNum));
    要调用两个函数,其实如果单纯取得EDT类型或者Enum类型的ID不需要这么周折,完全可以用一个内置函数来实现:
    extendedTypeNum(AccountNum);
    当然Enum有对应的EnumNum()这个内置函数,看上去后面的方法简洁多了。
    typeId()这个方法还是有其用武之地的,在有些场景下需要传入的参数带有其原始数据类型信息,比如最常见的Runbase框架下通过代码添加控件的情况,服务端代码需要知道客户端代码是否为UserType(即:EDT类型)然后做相应的处理,这时用typeId()这个方法就方便多了,否则客户端每次调用还要传一个参数过去表示是否为UserType,估计会不怎么爽,呵呵。
    当然typeId()这个方法可能还有其他用武之地。
  • 相关阅读:
    JQuery直接调用asp.net后台WebMethod方法
    26个Jquery使用小技巧
    SQL 基本知识
    JQuery 基本知识
    ASP.NET CheckBoxList Operations with jQuery
    asp.net 锚点
    delphi 数据连接规范
    删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录
    org.hibernate.QueryException: could not resolve property: address of:
    java.lang.ArithmeticException: / by zero
  • 原文地址:https://www.cnblogs.com/Farseer1215/p/1026641.html
Copyright © 2020-2023  润新知