Overlaying several CLR reference fields with each other in explicit struct?
.net, c#, clr, struct
Solution
I can't see how the explicit-layout version can be verifiable without the runtime injecting extra checks anyway, since it allows you to see a non-null reference to something that isn't of the declared type.
This would be safer:
struct Overlaid { // could also be a class for reference-type semantics
private object asObject;
public object AsObject {get {return asObject;} set {asObject = value;} }
public Foo AsFoo { get {return asObject as Foo;} set {asObject = value;} }
public Bar AsBar { get {return asObject as Bar;} set {asObject = value;} }
}
No risk of torn references etc, and still only a single field. It doesn't involve any risky code, etc. In particular, it doesn't risk something silly like:
[FieldOffset(0)]
public object AsObject;
[FieldOffset(0)]
public Foo AsFoo;
[FieldOffset(1)]
public Bar AsBar; // kaboom!!!!
Another issue is that you can only support a single field this way unless you can guarantee the CPU mode; offset 0 is easy, but it gets trickier if you need multiple fields and need to support x86 and x64.
Problem
Edit: I'm well aware of that this works very well with value types, my specific question is about using this for reference types. Edit2: I'm also aware that you can't overlay reference types and value types in a struct, this is just for the case of overlaying several reference type fields with each other. I've been tinkering around with structs in .NET/C#, and I just found out that you can do this: ``` 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(); } } } ``` Basically circumventing having to do dynamic casting during runtime by using a struct that has an explicit field layout and then accessing the object inside as it's correct type. Now my question is: Can this lead to memory leaks somehow, or any other undefined behavior inside the CLR? Or is this a fully supported convention that is usable without any issues? I'm aware that this is one of the darker corners of the CLR, and that this technique is only a viable option in very few specific cases.