第四十式:C# 不安全代码 (禁术)

绝世
秘籍
冲儿,C# 为了保护大家,把直接操作内存(指针)的能力封印了。
但有时候为了追求极致的速度(或者调用古老的 C 语言代码),我们不得不解开封印。
这叫不安全代码 (Unsafe Code)
听起来很危险,会不会走火入魔?
非常危险!一旦你用指针指错了地方(野指针),程序会立刻暴毙,连异常都捕获不到!
所以必须加上 unsafe 关键字,以示警戒。

1. 启用禁术 - 揭开封印

首先,你得在项目文件 (.csproj) 里允许不安全代码。


true
        

2. 指针 (Pointer) - 隔空点穴

指针存的是内存地址,不是值。


unsafe
{
    int a = 10;
    int* p = &a; // & 取地址:p 指向了 a 的内存地址

    Console.WriteLine((long)p); // 输出一个内存地址(如 1407328000)

    *p = 20; // * 解引用:通过地址修改值
    Console.WriteLine(a); // a 变成了 20!
}
        

3. fixed - 定身术

因为 C# 有个“清道夫”(GC),它会偷偷移动内存里的对象(整理碎片)。

如果你拿着一个地址,结果对象被 GC 移走了,你就指了个寂寞。

所以必须用 fixed 把对象在内存里,不让 GC 动它。


int[] arr = { 1, 2, 3 };

unsafe
{
    fixed (int* p = arr) // 钉住数组
    {
        // 现在可以安全地用指针遍历数组了
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine(*(p + i)); // 指针算术
        }
    }
}
        
除非你是写高性能图像处理、驱动程序或者调用 Windows API,否则千万别用这一招!
C# 的安全环境是无数先辈用鲜血换来的,不要轻易打破。
💀

动手时刻:交换灵魂

编写一个 unsafe 方法 Swap(int* a, int* b)

用指针来交换两个整数的值。

(注意:这段代码可能需要在 VS Code 中配置 AllowUnsafeBlocks 才能运行)

查看参考答案

unsafe static void Swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

unsafe static void Main()
{
    int x = 1, y = 2;
    Swap(&x, &y);
    Console.WriteLine($"x={x}, y={y}");
}
                    

成就解锁:【黑魔法师】 获得:死灵之书