gpt4 book ai didi

c# - 给定对结构的托管引用,如何获取对偏移量字段的托管引用?

转载 作者:行者123 更新时间:2023-11-30 21:28:34 25 4
gpt4 key购买 nike

我正在尝试在 C# 中实现固定大小的数组,这些数组由 hacky 类型级数字参数化。参见 GitHub

我想实现一个像这样工作的方法:

static ref T Ref(this ref TContainer container, int index)
where T: unmanaged
where TContainer: unmanaged
=> ref container[index];

现在的问题是:我知道,TContainer 内部由 N 个 T 类型的字段组成。但它实际上并没有实现索引操作(或任何接口(interface))。

我能做的是:

CheckIndex(index);
fixed (TContainer* self = &container) {
T* data = (T*)self;
return ref data[index];
}

这与 unsafe 一起编译,但我有两个问题:

  1. 是否会正确跟踪这样检索到的托管引用的生命周期?
  2. 在这种情况下使用fixed 是否有任何性能成本? (例如 GC 固定、别名问题等)

此外,即使我将参数类型 ref TContainer 替换为 ,上面带有 fixedreturn ref 的示例也会编译>TContainer,或者,应该是一样的,只是将其声明为实例成员而不是扩展方法。它甚至可以在示例测试用例中工作,但我不明白为什么会这样,因为在正常情况下,不能从结构实例方法返回 ref this.field

最佳答案

回答您的问题:

  1. 是的,因为您在固定时将非托管指针重建回托管指针;托管指针在任何时候都不能无效
  2. 不,fixed使用非常低的开销机制 - 基本上,fixed只是将局部变量标记为具有特殊含义;当 GC 运行时,它已经遍历堆栈帧,当它这样做时,它会查找这些局部变量并注意它们的值应被视为已固定

但是!听起来你真正想要的概念是 Span<T> (或 Memory<T> )-一个 Span<T>基本上是一个使用托管指针的“范围”。

这是一个不使用 unsafe 的版本:

public static ref T Ref<T, TContainer>(this ref TContainer container, int index)
where TContainer : unmanaged
where T : unmanaged
{
if (index < 0 || Unsafe.SizeOf<T>() * (index + 1) > Unsafe.SizeOf<TContainer>())
throw new ArgumentOutOfRangeException(nameof(index));
ref T first = ref Unsafe.As<TContainer, T>(ref container);
return ref Unsafe.Add<T>(ref first, index);
}

请注意,它仍然是“不安全的”。

关于c# - 给定对结构的托管引用,如何获取对偏移量字段的托管引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56373244/

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