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()这个方法可能还有其他用武之地。

转载于:https://www.cnblogs.com/Farseer1215/archive/2008/01/05/1026641.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值