You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中生成指针数组?代码优化场景求助

解决方案:简化Unity Tick检查逻辑的正确实现

为什么你的写法报错

  1. int*[] ticks = new int*[4];:C#中直接使用指针需要开启unsafe上下文,Unity默认禁用该选项,且裸指针容易因GC内存移动引发错误,需配合fixed关键字固定变量地址,不推荐在Unity项目中随意使用。
  2. ref int[] ticks = new ref int[4];:C#语法不支持直接创建引用类型数组,这种写法本身就不符合语言规范。

推荐方案:安全的无指针实现(无需unsafe)

通过提取通用逻辑+辅助方法/结构体的方式,既精简代码又避免内存风险,以下提供两种简洁实现:

方案1:提取通用处理方法(最易维护)

把重复的Tick检查逻辑封装成一个私有方法,然后逐个传入状态和Tick变量的引用,代码可读性高,兼容性强:

private void CheckTicks()
{
    // 封装通用Tick检查逻辑
    void ProcessTick(ref bool state, ref int tick, bool invertedCheck = false, Action onComplete = null)
    {
        bool shouldCheck = invertedCheck ? state : !state;
        if (shouldCheck)
        {
            if (tick >= DEFAULT_CYCLE_END_VALUE)
            {
                tick = DEFAULT_CYCLE_START_VALUE;
                state = !state;
                onComplete?.Invoke();
            }
            else
            {
                tick++;
            }
        }
    }

    // 批量调用处理方法
    ProcessTick(ref canEatFood, ref canEatTick);
    ProcessTick(ref canTakeBath, ref canBatheTick);
    ProcessTick(ref canPlay, ref canPlayTick);
    ProcessTick(ref beenPet, ref beenPetTick, true, CheckIfPetsShouldKill);
}

方案2:使用Ref Struct批量遍历(C# 7.3+支持)

通过自定义ref struct存储状态和Tick的引用,再用Span批量遍历处理,适合变量数量较多的场景:

// 定义仅用于栈的引用结构体,避免堆内存分配
private ref struct TickStatePair
{
    public ref bool State;
    public ref int Tick;
    public bool IsInvertedCheck; // 标记是否反向检查(如beenPet是true时触发)
    public Action OnTickComplete; // Tick完成后的回调
}

private void CheckTicks()
{
    // 创建Span存储所有状态-Tick配对
    var tickPairs = new Span<TickStatePair>(new[]
    {
        new TickStatePair { State = ref canEatFood, Tick = ref canEatTick, IsInvertedCheck = false },
        new TickStatePair { State = ref canTakeBath, Tick = ref canBatheTick, IsInvertedCheck = false },
        new TickStatePair { State = ref canPlay, Tick = ref canPlayTick, IsInvertedCheck = false },
        new TickStatePair { State = ref beenPet, Tick = ref beenPetTick, IsInvertedCheck = true, OnTickComplete = CheckIfPetsShouldKill }
    });

    // 遍历处理所有配对
    foreach (ref var pair in tickPairs)
    {
        bool shouldCheck = pair.IsInvertedCheck ? pair.State : !pair.State;
        if (shouldCheck)
        {
            if (pair.Tick >= DEFAULT_CYCLE_END_VALUE)
            {
                pair.Tick = DEFAULT_CYCLE_START_VALUE;
                pair.State = !pair.State;
                pair.OnTickComplete?.Invoke();
            }
            else
            {
                pair.Tick++;
            }
        }
    }
}

可选方案:Unsafe指针实现(不推荐)

如果一定要用指针,需先在Unity编辑器中开启Allow unsafe code(路径:Edit > Project Settings > Player > Other Settings > Allow unsafe code),再使用以下代码:

private unsafe void CheckTicks()
{
    // 固定变量地址,防止GC移动内存
    fixed (int* eatTickPtr = &canEatTick, bathTickPtr = &canBatheTick, playTickPtr = &canPlayTick, petTickPtr = &beenPetTick)
    fixed (bool* eatStatePtr = &canEatFood, bathStatePtr = &canTakeBath, playStatePtr = &canPlay, petStatePtr = &beenPet)
    {
        int*[] tickPtrs = { eatTickPtr, bathTickPtr, playTickPtr, petTickPtr };
        bool*[] statePtrs = { eatStatePtr, bathStatePtr, playStatePtr, petStatePtr };
        bool[] invertedChecks = { false, false, false, true };
        Action[] callbacks = { null, null, null, CheckIfPetsShouldKill };

        for (int i = 0; i < tickPtrs.Length; i++)
        {
            bool shouldCheck = invertedChecks[i] ? *statePtrs[i] : !*statePtrs[i];
            if (shouldCheck)
            {
                if (*tickPtrs[i] >= DEFAULT_CYCLE_END_VALUE)
                {
                    *tickPtrs[i] = DEFAULT_CYCLE_START_VALUE;
                    *statePtrs[i] = !*statePtrs[i];
                    callbacks[i]?.Invoke();
                }
                else
                {
                    (*tickPtrs[i])++;
                }
            }
        }
    }
}

注意:指针写法可读性差,易引发内存错误,仅在极端性能需求场景下考虑使用。


内容的提问来源于stack exchange,提问作者Dylan Beaulieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:05:25