我想假设这个问题的目的是检查是否至少有一种方法,即使通过最不安全的黑客,仍然保持对非blittable值类型的引用.我知道这种设计类型与犯罪相当; 除了学习之外,我不会在任何实际案例中使用它.因此,请接受现在阅读异常不安全的代码.
我们知道可以以这种方式存储和增加对blittable类型的引用:
unsafe class Foo
{
void* _ptr;
public void Fix(ref int value)
{
fixed (void* ptr = &value) _ptr = ptr;
}
public void Increment()
{
var pointer = (int*) _ptr;
(*pointer)++;
}
}
Run Code Online (Sandbox Code Playgroud)
在安全性方面,上述类别可以与虚空中的跳跃相媲美(没有双关语意),但正如这里已经提到的那样.如果在堆栈上分配的变量传递给它,然后调用方法的作用域终止,则可能会遇到错误或显式访问冲突错误.但是,如果您执行这样的程序:
static class Program
{
static int _fieldValue = 42;
public static void Main(string[] args)
{
var foo = new Foo();
foo.Fix(ref _fieldValue);
foo.Increment();
}
}
Run Code Online (Sandbox Code Playgroud)
在卸载相关应用程序域之前,不会处理该类,因此适用于该字段.老实说,我不知道高频堆中的字段是否可以重新分配,但我个人认为不是.但是现在让我们放弃安全(如果可能的话).在阅读了这个和这些问题后,我想知道是否有办法为非blittable静态类型创建类似的方法,所以我制作了这个程序,它实际上有效.阅读评论以了解它的作用.
static class Program
{
static Action _event;
public static …Run Code Online (Sandbox Code Playgroud) TypedReference和ArgIterator?)?我怀疑它在编译器中是硬编码的,因为错误CS0610的文档指出:
有些类型不能用作字段或属性.这些类型包括......
在我看来哪些类型可以扩展 - 但我可能是错的.
我在SO上搜索了一下,虽然我明白以编程方式抛出编译器错误无法完成,但我找不到任何来源说明某些"特殊"类型的行为无法复制.
即使问题主要是学术问题,也可能会有一些答案.例如,有时可以确保某个对象的生命周期被约束到创建它的方法块.
编辑: RuntimeArgumentHandle是一种(未提及)不可存储的类型.
编辑2:如果它可以有任何用途,似乎CLR也以不同的方式处理这些类型,如果不仅仅是编译器(仍然假设类型与其他类型没有任何区别).例如,以下程序将提出一个TypeLoadException问题TypedReference*.我已经对它进行了调整以缩短它,但你可以随心所欲地解决它.例如,void*将指针的类型更改为不会抛出异常.
using System;
unsafe static class Program
{
static TypedReference* _tr;
static void Main(string[] args)
{
_tr = (TypedReference*) IntPtr.Zero;
}
}
Run Code Online (Sandbox Code Playgroud)