这部分内容没找到相关文档参考,只是结合在VS里debug结果猜想一下。
首先解决一个问题,扩展类是什么时候实例化的,这个很容易求证,用VS debug跟踪一下就知道了。

 1 static public void Main(Args _args)
 2     {
 3         Person person = new Person();
 4         
 5         person.Height = 1.75;
 6         person.Weight = 70;
 7 
 8         info (num2Str(person.BMI(),0 ,2, 0, 0));
 9         Person::Introduce();
10     }

执行到第5行,第一次引用到扩展类实例属性的时候会调用Person_Extension的new方法进行实例化。
如果最开始不调用实例属性,直接调用Person_Extension的实例方法会进行实例化吗?

 1 static public void Main(Args _args)
 2     {
 3         Person person = new Person();
 4         
 5         person.Stage();
 6 
 7         person.Height = 1.75;
 8         person.Weight = 70;
 9 
10         info (num2Str(person.BMI(),0 ,2, 0, 0));
11         Person::Introduce();
12     }

执行到第5行调用Stage这个实例方法的时候,并不会调用Person_Extension的new方法进行实例化。
也就是说Person这个实例对象在调用Person_Extension的实例方法的时候,Person_Extension还没实例化,正常情况下如果对象没有实例化就调用它的实例方法,会报错的。
跟踪进Stage方法,用变量跟踪查看this
D365F&O扩展类(三)

 VS给出的提示是this在静态方法中无效,所以这个Stage方法虽然签名是个实例方法,但是可能只是个语法糖,实质上跟C#的扩展方法一样,是个静态方法,只不过被X++封装成了个实例方法,这样语义上好理解。

在监视器里看到一个@this的变量,它的构成是Person的类变量 + Person_Extension。

 实例化后的对象person在调用扩展类的方法时,实际上是按照C#扩展方法的方式调用的,Person_Extension的实例方法,比如Stage,实际上是静态方法,person对象在调用stage的时候,把指向person对象的引用作为方法的第一个参数隐形传给了该方法,这样才能解释为什么在Person_Extension未实例化的情况下还可以调用实例Stage方法,以及在变量追踪的时候,查看this变量会提示this在静态方法中无效。

Person_Extension实例化出来只是为了存放扩展的实例属性的值,如测试例子中的Height和Weight,只有调用到实例属性的时候才会实例化扩展类,如果扩展类没有包含实例属性,可能都扩展类都不会被实例化。
以上纯属猜想,我们使用X++的扩展类时把它当做一般的类来使用理解它的语义就可以了,至于底层的实现猜想一下只是为了满足好奇心。
D365F&O的扩展类学习到此结束。

相关文章:

  • 2022-12-23
  • 2021-10-09
  • 2021-08-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-15
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-02-21
  • 2021-12-03
  • 2021-06-19
  • 2021-06-16
  • 2022-01-10
相关资源
相似解决方案