代码“Console.WriteLine(“Hello G#”);”会在哪里发出?它将在其基生成的emit块中发出。[(That reminds be of the definition of a normal)]OK,那么pre和post实际上也是emit块,只不过它们定义了发出代码的位置(方法体的前面和方法体的后面)。对于上面的代码片断,我们需要提供一个上下文环境来说明一下这些代码是在哪里发出的。
在上面的代码片断中,我们在DisplayParts生成的定义中创建了两个emit对象partOne和partTwo。然后我们使用partOne加花括号定义了一个emit块。花括号之间的所有代码都将被发出到partOne的局部存储(Local Store)中,当我们在partOne对象上调用Emit方法时,将会返回这个局部存储。最后,注意该代码段的pre块中调用了返回值类型为emt的DisplayParts。[Since the emitted code is not caught it is emitted into the pre block.]
public generator Base { protected virtual generation ChangeClient : target Client { property public string * { get { post { Console.WriteLine(value); } } set { pre { Console.WriteLine(value); } } }
比起静态生成,自适应生成的优势在于第三方也可以提供生成框架和组件。第三方开发者可以通过创建幻象目标(Phantom Target)来以他们一无所知的代码基作为目标。幻象目标并不存在于生成框架或目标框架中。当开发者希望使用一个第三方的生成器时,他们可以加入幻象的命名空间、类、方法并将生成的代码重定位到他们的代码基中适当的位置。 public class Client
现在的CLR能够在运行时动态地注入IL代码,这发生在程序集加载时,通过Profiler API完成。然而这种途径还存在着一系列的安全问题,因为它禁用了CAS,因此还需要深入的研究才能找到一种切实可行的解决方案。我们将在下面描述这是如何完成的。 CAS和注入特性 现在已经有望解决注入代码所引发的安全问题了。G#的安全模型能够确保只有你希望他注入代码的人才能注入代码,并且这些代码只能限制在你所允许的代码访问安全(CAS,Code Access Security)许可中。通过使用元数据,你可以声明你授予注入代码的权限。这仍需要定义一种语法并加入建议[Still need to define this syntax and open to suggestions.]。所有包含生成器和生成的程序集都必须被赋予一个强密钥,然后为目标程序集添加一个带有该公共密钥记号的Injector特性。只有在Injector中指出了强密钥的程序集才能运行和注入代码。