C# 强制执行内存级别强制转换

C# 强制执行内存级别强制转换,c#,memory,casting,low-level,C#,Memory,Casting,Low Level,Iirc从C开始,你可以有这样一个语句: char* str = "1234"; int nonStr = *((int*)str); (我故意将字符串设为4个字符,这样在平均情况下,它将具有与整数相同的字节数。)这将取消对存储str的内存的引用,并在它是整数时为您提供值(522207554如果我正确转换) 有没有办法在C#中做同样的事情?我知道这是一个低级别的内存操作,通常对C#程序员来说是隐藏的,我这样做只是为了一个教学练习。联合模拟就足够了吗 您正在寻找C#的不安全的功能 给你。对“C#

Iirc从C开始,你可以有这样一个语句:

char* str = "1234";
int nonStr = *((int*)str);
(我故意将字符串设为4个字符,这样在平均情况下,它将具有与整数相同的字节数。)这将取消对存储
str
的内存的引用,并在它是整数时为您提供值(
522207554
如果我正确转换)


有没有办法在C#中做同样的事情?我知道这是一个低级别的内存操作,通常对C#程序员来说是隐藏的,我这样做只是为了一个教学练习。

联合模拟就足够了吗


您正在寻找C#的
不安全的
功能


给你。对“C#unsafe pointer dereference”的一般搜索会显示许多结果。

您可以使用unsafe context和
fixed
语句执行此操作:

static unsafe void Main(string[] args)
{
    string str = "1234";
    fixed(char* strPtr = str)
    {
        int* nonStr = (int*)strPtr;
        Console.WriteLine(*nonStr);
    }
}
印刷品

3276849

“教学”练习!当然,我们希望鼓励良好的习惯,而不是滥用这样的指针——特别是在C#中。如果您想教授指针滥用,至少要在适当的上下文中进行,即在低级别/OS环境中使用C/C++。不是C#。可能重复@Skizz滥用它们的全部目的是“指出”它们可能被滥用,甚至是意外地滥用。我想解释一下幕后的记忆发生了什么,这样学生们就会明白为什么他们会得到一个
无效的CastException
!我不打算教他们用这种方式编写“真正”的程序。在.NET中有
IntPtr
对象,您可以在
不安全的
块中进行指针操作。首先,您试图操纵的指针是什么?除非它是一个IntPtr、封送的东西或在不安全的块中创建的指针,否则我认为就低级别内存操作而言,您无法使用它。@just.other.programmer:
str
指向一个静态分配的
char
s数组,严格的别名规则表示(大约)您不能通过指向不同类型的指针来访问一种类型的对象(这不属于少数例外情况)。这允许某些有时需要的优化。使用
memcpy(&nonsr,str,sizeof(nonsr))
可以删除问题中的代码的未定义行为。(这调用了一个允许的异常,非
char
事物可以用作
char
,但反之亦然。)其他地方有更多信息。
char
在C#中是一个双字节结构(UTF-16编码),因此您希望字符串中包含两个字符。您可以在这里看到:十六进制中的3276849是0x00320031(“34”未被复制)。