>情况
我正在阅读有关 C# 7.x 到 8.0 中新增功能的 MSDN 文档,并找到了这些文章(doc1、doc2)
所以我决定创建一个小测试。
法典
指针.cs
internal readonly unsafe struct Pointer<T>
where T : unmanaged
{
private readonly void* mValue;
internal Pointer(T value)
{
//fixed (T* val = &value) <--- Error: You cannot use the fixed statement to take the adress of an already fixed expression.
// mValue = val;
mValue = &value;
}
public static implicit operator Pointer<T>(T value)
{
return new Pointer<T>(value);
}
public static implicit operator string(Pointer<T> value)
{
var ptr = (T*)value.mValue;
return ptr->ToString(); // returns random values (maybe adresses).
}
}
程序.cs
class Program
{
static void Main(string[] args)
{
Pointer<int> ptr = 2;
Console.WriteLine(ptr); // prints random values (maybe adresses).
}
}
问题
为什么不允许我在构造函数中使用fixed
语句。我的意思是这是有道理的,它抛出了一个错误。我已经说过T
应该unmanaged
,所以我认为它在内部自动使用fixed
关键字。但是,如果确实如此,那么为什么我会得到随机值。
根据非托管类型的文档,T 将是某种不能包含对托管类型的引用的值类型。因此,它将在堆栈上分配。当构造函数返回时,堆栈将被弹出,指针将指向某个未定义的值。您不能将fixed
用于堆栈上分配的内容,因为垃圾回收器无论如何都无法移动,因此被视为"固定"。
我对正在发生的事情的理解:
-
在这里,您可以获得堆栈中
int
的按值副本。internal Pointer(T value)
-
在这里,您将获取指向堆栈中
int
的指针。mValue = &value;
-
然后构造函数完成,int 从堆栈中弹出,指针是孤立的。
-
堆栈上放了其他东西,例如
Pointer<T>
结构本身,指针现在会导致垃圾。public static implicit operator string(Pointer<T> value)
-
您将垃圾视为
int
.var ptr = (T*)value.mValue;