静态成员是否存储在 .NET 中的固定位置?

Are static members stored at fixed locations in .NET?

考虑以下代码:

class Foo
{
    static readonly Guid guid = Guid.Parse("...");
}

初始化后静态guid字段的底层地址可以改变吗?如果不是,这个地址如何获取?

常量呢?

注意:我知道引用类型通常可以被 GC 移动(不管是否有一个带有句柄的静态变量),但这对静态值类型和常量有何作用?

这个问题出现是因为我们正在处理一些需要与非托管 API 互操作的代码,我们希望避免将字节额外复制到 HGlobal 中(如果它们已经存在)在内存中的固定地址开始。

我更想知道 CLI 标准对此有何规定(相对于特定的 .NET 实现 所做的),因为我更喜欢不依赖的健壮代码关于巧合的实施细节。

据我所知,标准没有提到这一点 - 这并不奇怪,因为它绝对是您在托管运行时中不应该关心的实现细节。

既然你想在非托管互操作中重用这个地址,我可以让你放心——你不能真正访问不安全代码中那些静态字段的地址。我不知道为什么(可能是某种保护措施),但似乎是这样。

当然,noöne 会阻止您创建自己的助手类型,为您想要的任何东西分配一块非托管内存,并用读取非托管内存的属性替换这些字段 - 您甚至不必关心GC,因为静态字段只会随着域(通常是进程)一起消失。