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

.NET Native UWP应用中Span<T>及相关类型无法正常工作

解决.NET Native UWP应用中Span及相关类型的异常问题

我看到你在.NET Native编译的UWP应用里碰到了Span<T>、ReadOnlySpan<T>这类类型没法正常工作的问题,尤其是递归使用Slice方法的场景。结合你给出的复现步骤,我来帮你梳理问题原因和可行的解决方案:

完整问题复现步骤(补充你未写完的代码逻辑)

  • 打开安装了最新更新的Visual Studio 2017
  • 创建目标版本为10240的UWP项目(实际所有UWP版本都存在该问题,这个版本不是必须的)
  • 从NuGet安装System.Memory包(得勾选「包含预发行版」,因为早期正式版对.NET Native的支持不够完善)
  • 在MainPage.cs里添加如下完整代码:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    void Recursive(ReadOnlySpan<char> param)
    {
        if (param.Length == 0) return;
        tx1.Text += Environment.NewLine;
        tx1.Text += new string(param.ToArray());
        // 递归调用Slice截取从索引1开始的子Span
        Recursive(param.Slice(1));
    }

    // 触发测试
    Recursive("Hello World".AsSpan());
}
  • 切换到Release模式(因为.NET Native只在Release编译时启用),编译运行应用,会发现应用崩溃或者输出结果不符合预期。

问题根源

这是因为早期的.NET Native编译器对Span<T>这类值类型的递归处理存在缺陷——当Span<T>作为递归方法的参数时,编译器的优化逻辑会破坏Span<T>的内部结构,进而导致内存访问异常或者数据错误。另外,早期版本的System.Memory包对.NET Native的适配也没做到位。

可行解决方案

方案1:升级开发环境和NuGet包

这是最彻底的解决办法:

  • 把Visual Studio 2017升级到15.9及以上版本(微软在后续更新里修复了.NET Native对Span<T>的编译问题)
  • 将System.Memory包升级到2.0.0及以上的正式版(不用再用预发行版了,正式版已经完善了对.NET Native的支持)

方案2:调整代码逻辑,避免递归传递Span

如果暂时没法升级环境,可以换个写法,不在递归方法里直接传Span<T>:

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    string input = "Hello World";
    void Recursive(int startIndex)
    {
        if (startIndex >= input.Length) return;
        // 在递归方法内部根据索引生成Span
        ReadOnlySpan<char> param = input.AsSpan(startIndex);
        tx1.Text += Environment.NewLine;
        tx1.Text += new string(param.ToArray());
        Recursive(startIndex + 1);
    }

    Recursive(0);
}

通过传递起始索引而非直接传递Span<T>,绕开.NET Native编译器的缺陷。

方案3:禁用.NET Native对Span的特定优化

在项目的Default.rd.xml文件里添加下面的配置,告诉.NET Native编译器不要优化Span<T>相关类型:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
    <Assembly Name="System.Memory" Dynamic="Required All"/>
    <Type Name="System.Span`1" Dynamic="Required All"/>
    <Type Name="System.ReadOnlySpan`1" Dynamic="Required All"/>
  </Application>
</Directives>

这个配置能强制.NET Native保留Span<T>的完整类型信息,避免优化导致的异常。

验证方式

修改完成后切换到Release模式编译运行,看看应用是不是能正常输出递归截取的字符串,而且没有崩溃或者异常情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:42:44