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

如何让C#函数接受多种类型的Unity NativeArray参数?

解决方案

针对你遇到的NativeArray重载函数代码重复问题,以下几种方法可以在不复制数组的前提下合并逻辑:

方法1:泛型函数结合MemoryMarshal.Cast实现无复制类型转换

利用ushort和short都是16位值类型、内存布局兼容的特性,通过MemoryMarshal.Cast在只读场景下安全转换视图,统一处理逻辑:

using System.Runtime.InteropServices;
using Unity.Collections;

public void Func<T>(NativeArray<T> a) where T : unmanaged
{
    // 限制仅支持目标类型
    if (typeof(T) != typeof(ushort) && typeof(T) != typeof(short))
        throw new ArgumentException("仅支持ushort或short类型的NativeArray");

    // 无复制转换为ushort的只读Span
    ReadOnlySpan<ushort> span = MemoryMarshal.Cast<T, ushort>(a.AsReadOnlySpan());

    // --------------------------
    // 这里写入原函数的核心逻辑,例如:
    foreach (ushort val in span)
    {
        // 处理逻辑
    }
    // --------------------------
}
  • 优势:无需复制数组,性能无损耗;通过泛型实现单一入口;MemoryMarshal.Cast是安全的只读转换,不会修改原始数据。

方法2:提取核心逻辑到私有函数,保留轻量重载

如果不想用泛型,可以把重复逻辑抽到接受ReadOnlySpan<ushort>的私有函数,重载函数仅做无复制转换:

using System.Runtime.InteropServices;
using Unity.Collections;

public void Func(NativeArray<ushort> a)
{
    InternalProcess(a.AsReadOnlySpan());
}

public void Func(NativeArray<short> a)
{
    // 无复制转换为ushort的Span
    InternalProcess(MemoryMarshal.Cast<short, ushort>(a.AsReadOnlySpan()));
}

private void InternalProcess(ReadOnlySpan<ushort> span)
{
    // --------------------------
    // 这里写入原函数的核心逻辑
    // --------------------------
}
  • 优势:避免泛型的类型检查,调用方仍保持原有的参数类型入口,无学习成本。

方法3:Unsafe代码直接操作内存指针(需开启unsafe支持)

如果项目允许unsafe代码,可以直接获取NativeArray的只读指针,转换为ushort*统一处理:

using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;

public unsafe void Func<T>(NativeArray<T> a) where T : unmanaged
{
    if (typeof(T) != typeof(ushort) && typeof(T) != typeof(short))
        throw new ArgumentException("仅支持ushort或short类型的NativeArray");

    ushort* ptr = (ushort*)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(a);
    int length = a.Length;

    // --------------------------
    // 这里写入原函数的核心逻辑,例如:
    for (int i = 0; i < length; i++)
    {
        ushort val = ptr[i];
        // 处理逻辑
    }
    // --------------------------
}
  • 注意:需要在Unity项目设置中开启"Allow unsafe code"选项;确保NativeArray未被释放且处于有效状态。

所有方法均不会复制数组内容,仅通过内存视图转换实现逻辑复用,性能与原重载函数一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:35:17