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

实现Amazon Glacier Tree Hash时关于Memory<T>底层数组访问、HashAlgorithm适配及SonarQube Roslyn警告处理的技术问询

问题2:存储在Memory实例中的数据是否也可以通过用于创建它的原数组访问?

完全可以。当你用new Memory<byte>(buff)创建Memory<T>时,它只是原数组的一个"视图",没有复制任何数据。写入Memory<T>的内容会直接同步到原数组中,反之亦然。

举个直观的例子:

byte[] buff = new byte[3] {1,2,3};
Memory<byte> memory = new Memory<byte>(buff);
memory.Span[0] = 100;
// 此时buff[0]的值也变为100
Console.WriteLine(buff[0]); // 输出100

你可以通过memory.TryGetArray(out ArraySegment<byte> segment)验证:segment.Array就是原数组,segment.Offset是Memory<T>在数组中的起始索引,segment.Count是Memory<T>的长度。


问题3:是否存在无需复制数据即可将Memory实例中的数据作为数组访问的其他方式?

最安全且通用的方式是使用Memory<T>.TryGetArray方法,它能获取到Memory<T>底层的ArraySegment<byte>,通过这个段你可以直接访问原数组,完全不需要复制:

if (memory.TryGetArray(out ArraySegment<byte> segment))
{
    // 直接访问原数组的指定范围
    byte firstByte = segment.Array[segment.Offset];
    // 也可以传入你原有的ComputeHash方法
    chunkHashes[idx++] = this.ComputeHash(segment.Array, segment.Offset, bytesRead);
}

这个方法的优势在于:如果Memory<T>不是基于托管数组(比如来自非托管内存),TryGetArray会返回false,你可以做降级处理(比如复制数据)。但在你的场景中,Memory<T>是用自己创建的byte[]初始化的,所以肯定会返回true,可以放心使用。


问题4:若以上方案均不可行,如何在SonarQube中屏蔽该外部Roslyn警告?

如果暂时无法修改代码,你可以通过代码层面的编译指令精准屏蔽这个警告,不会影响其他规则的检查:

  1. 确认警告的规则ID:你遇到的是Roslyn的CA1835规则(推荐使用ReadAsync/WriteAsync的Memory<T>重载)。
  2. 在需要屏蔽的代码块前后添加指令:
#pragma warning disable CA1835 // 临时屏蔽该警告
byte[] buff = new byte[Mio]; int bytesRead; 
while ((bytesRead = await inputStream.ReadAsync(buff, 0, Mio)) > 0) 
{ 
    // Process the bytes read 
}
#pragma warning restore CA1835 // 恢复警告检查

如果整个项目都不需要这个规则,也可以在项目文件(.csproj)中添加全局配置:

<PropertyGroup>
  <NoWarn>CA1835</NoWarn>
</PropertyGroup>

注意:不推荐在SonarQube服务器全局关闭规则,除非团队一致认为该规则不适用,否则会影响其他代码的质量检查。


内容的提问来源于stack exchange,提问作者Nathan.Eilisha Shiraini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:17:44