了解 C# 中的非托管关键字
Understanding unmanaged keyword in C#
情况
我正在阅读有关 C# 7.x 到 8.0 中新增功能的 MSDN 文档,并找到了这些文章 (doc1, doc2)
所以我决定创建一个小测试。
代码
Pointer.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).
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
Pointer<int> ptr = 2;
Console.WriteLine(ptr); // prints random values (maybe adresses).
}
}
问题
为什么不允许我在构造函数中使用 fixed
语句。我的意思是这是有道理的,它会抛出一个错误。我说过 T
应该是 unmanaged
,所以我认为它在内部自动使用 fixed
关键字。但是如果它这样做那么为什么我得到随机值。
根据 documentation for unmanaged types T 将是某种不能包含对托管类型的引用的值类型。因此它将分配在堆栈上。当构造函数 returns 时,堆栈将被弹出,指针将指向某个未定义的值。您不能对堆栈上分配的内容使用 fixed
,因为无论如何都不能被垃圾收集器移动,因此被认为是 '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;
情况
我正在阅读有关 C# 7.x 到 8.0 中新增功能的 MSDN 文档,并找到了这些文章 (doc1, doc2)
所以我决定创建一个小测试。
代码
Pointer.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).
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
Pointer<int> ptr = 2;
Console.WriteLine(ptr); // prints random values (maybe adresses).
}
}
问题
为什么不允许我在构造函数中使用 fixed
语句。我的意思是这是有道理的,它会抛出一个错误。我说过 T
应该是 unmanaged
,所以我认为它在内部自动使用 fixed
关键字。但是如果它这样做那么为什么我得到随机值。
根据 documentation for unmanaged types T 将是某种不能包含对托管类型的引用的值类型。因此它将分配在堆栈上。当构造函数 returns 时,堆栈将被弹出,指针将指向某个未定义的值。您不能对堆栈上分配的内容使用 fixed
,因为无论如何都不能被垃圾收集器移动,因此被认为是 '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;