gpt4 book ai didi

c# - 在显式结构中将多个 CLR 引用字段相互重叠?

转载 作者:可可西里 更新时间:2023-11-01 08:47:01 24 4
gpt4 key购买 nike

编辑:我很清楚这对值类型非常有效,我的具体问题是关于将它用于引用类型。

Edit2:我还知道您不能在结构中叠加引用类型和值类型,这仅适用于将多个引用类型字段相互叠加的情况。

我一直在研究 .NET/C# 中的结构,我刚刚发现您可以这样做:

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1 {

class Foo { }
class Bar { }

[StructLayout(LayoutKind.Explicit)]
struct Overlaid {
[FieldOffset(0)] public object AsObject;
[FieldOffset(0)] public Foo AsFoo;
[FieldOffset(0)] public Bar AsBar;
}

class Program {
static void Main(string[] args) {
var overlaid = new Overlaid();
overlaid.AsObject = new Bar();
Console.WriteLine(overlaid.AsBar);

overlaid.AsObject = new Foo();
Console.WriteLine(overlaid.AsFoo);
Console.ReadLine();
}
}
}

通过使用具有显式字段布局的结构,然后访问正确类型的对象,基本上避免了在运行时必须进行动态转换。

现在我的问题是:这是否会以某种方式导致内存泄漏,或 CLR 内部的任何其他未定义行为?还是这是一个完全受支持的约定,可以毫无问题地使用?

我知道这是 CLR 的黑暗角落之一,而且这种技术仅在极少数特定情况下是可行的选择。

最佳答案

好吧,您发现了一个循环漏洞,CLR 允许这样做,因为所有重叠的字段都是对象。任何会让你直接弄乱对象引用的东西都会被 TypeLoadException 拒绝:

  [StructLayout(LayoutKind.Explicit)]
struct Overlaid {
[FieldOffset(0)]
public object AsObject;
[FieldOffset(0)]
public IntPtr AsPointer;
}

但是您可以通过给类字段来利用它。只要您只是读取字段值,就不会发生真正糟糕的事情,例如,您可以通过这种方式获取跟踪句柄的值。

然而,写入这些字段会导致 ExecutionEngineException。但是我认为,如果您能够正确猜出跟踪句柄的值,那么它就是一种利用。不过,实际使用非常接近于零。

关于c# - 在显式结构中将多个 CLR 引用字段相互重叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2703604/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com