gpt4 book ai didi

c# - 如何检查两个 Span 是否相交?

转载 作者:可可西里 更新时间:2023-11-01 08:47:38 26 4
gpt4 key购买 nike

考虑以下函数:

public static bool TryToDoStuff(ReadOnlySpan<byte> input, Span<byte> destination) {
...
}

此函数返回它是否能够根据 input 的内容在 destination 上“做事”。

我想检查 inputdestination“包裹”的内存区域是否相交,如果是,则抛出异常,因为这会破坏 input 的数据。 我该怎么做(没有反射或不安全代码)?

我知道我可以写一些 xmldoc 并警告用户参数不应该相交,但这是一个穷人的解决方案。

编辑:对于那些要求示例的人,Wazner 的示例很重要。

// On arrays
Span<byte> firstArray = new byte[10];
Span<byte> secondArray = new byte[10];
Intersects<byte>(firstArray.Slice(5, 5), firstArray.Slice(3, 5)); // Should throw
Intersects<byte>(firstArray.Slice(5, 5), secondArray.Slice(3, 5)); // Should not throw

// And on stackallocated memory
Span<byte> firstStack = stackalloc byte[10];
Span<byte> secondStack = stackalloc byte[10];
Intersects<byte>(firstStack.Slice(5, 5), firstStack.Slice(3, 5)); // Should throw
Intersects<byte>(firstStack.Slice(5, 5), secondStack.Slice(3, 5)); // Should not throw

最佳答案

有一种方法可以使用 System.Runtime.CompilerServices.Unsafe NuGet 包。它提供低级方法,例如 ByteOffsetSizeOf .

使用这些方法,您可以编写以下方法:

public static bool Intersects<T>(ReadOnlySpan<T> a, ReadOnlySpan<T> b) 
{
var elementSize = Unsafe.SizeOf<T>();
var distance = (long)Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(a), ref MemoryMarshal.GetReference(b));
if (distance < 0)
{
return -distance < b.Length * elementSize;
}
else if (distance > 0)
{
return distance < a.Length * elementSize;
}
return true;
}

此方法确定每个跨度中第一个元素之间的距离,以字节为单位。然后它确定此距离是否小于跨度中的项目数乘以跨度中单个元素的大小(以字节为单位)。

通过使用 Unsafe.SizeOf<T>我们甚至允许在非原始类型上使用此方法。字符串和类等引用类型是 native 整数 ( IntPtr.Size ) 的大小。

下面是几个表明该方法有效的测试用例:

// On arrays
Span<byte> firstArray = new byte[10];
Span<byte> secondArray = new byte[10];
Intersects<byte>(firstArray.Slice(5, 5), firstArray.Slice(3, 5)); // true
Intersects<byte>(firstArray.Slice(5, 5), secondArray.Slice(3, 5)); // false

// And on stackallocated memory
Span<byte> firstStack = stackalloc byte[10];
Span<byte> secondStack = stackalloc byte[10];
Intersects<byte>(firstStack.Slice(5, 5), firstStack.Slice(3, 5)); // true
Intersects<byte>(firstStack.Slice(5, 5), secondStack.Slice(3, 5)); // false

注意:System.Runtime.CompilerServices.Unsafe包需要使用 ref-returns,这是仅从 C# 7 开始可用的功能

关于c# - 如何检查两个 Span<T> 是否相交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51941177/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com