编辑:我很清楚这对于值类型非常有效,我的具体问题是将其用于引用类型.
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上避免在运行时通过使用具有显式字段布局的结构进行动态转换,然后以正确的类型访问内部对象.
现在我的问题是:这是否会以某种方式导致内存泄漏,或CLR内部的任何其他未定义的行为?或者这是一个完全支持的约定,可以使用而没有任何问题?
我知道这是CLR的一个黑暗角落,而且这种技术在极少数特定情况下才是可行的选择.
请考虑以下代码:
using System;
using System.Runtime.InteropServices;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
const string test = "ABCDEF"; // Strings are immutable, right?
char[] chars = new StringToChar{str=test}.chr;
chars[0] = 'X';
// On an x32 release or debug build or on an x64 debug build,
// the following prints "XBCDEF".
// On an x64 release build, it prints "ABXDEF".
// In both cases, we have changed the contents of 'test' without using
// any 'unsafe' code...
Console.WriteLine(test); …Run Code Online (Sandbox Code Playgroud)