c# - 如何将 fixed 与 Array 或 T[] 类型的变量一起使用?

标签 c# fixed unsafe

我正在开发一个 IEqualityComparer,它可以非常快速地比较基本类型的数组。我的计划是获取指向数组的指针并 memcmp 它们。像这样:

    public unsafe override bool Equals(T[] x, T[] y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x == null || y == null) return false;
        if (x.Length != y.Length) return false;

        var xArray = (Array)x;
        var yArray = (Array)y;
        fixed (void* xPtr = xArray) //compiler error 1
        fixed (T* yPtr = y) //compiler error 2
        {
            return memcmp(xPtr, yPtr, x.Length * this.elementSize);
        }
    }

fixed 语句不允许我固定 ArrayT[]

错误信息是:

1. Cannot implicitly convert type 'System.Array' to 'void*'
2. Cannot take the address of, get the size of, or declare a pointer to a managed type ('T')

现在,我实际上并不关心我是如何完成这项工作的(我不致力于这种确切的方法)。我如何memcmp 两个 T[] 我知道 T 是原始/blittable 类型?

我真的想避免切换类型并为每个有趣的类型创建专门的(和重复的)代码版本。由于性能限制,任何类型的反射解决方案都不可行(是的,我真的需要这里的性能 - 没有过早的优化警告适用,因为它在 Stack Overflow 上是习惯的)。

最佳答案

where I know that T is a primitive/blittable type

你知道,编译器不知道。 CLR 要求固定对象中的所有 不能再被垃圾收集器移动。对于一个数组,它包括它的数组元素。唯一符合条件的 T 是一种简单值类型,blittable。泛型不会为您提供将 T 限制为可 blittable 类型的方法。

您通常会将 memcmp() 的参数声明为 byte[]。然后 pinvoke 编码器已经做了正确的事情,并会在调用 memcmp() 之前固定 byte[] 数组。但是,这也不起作用,因为您也无法轻松地将 T[] 转换为 byte[]。您必须将自己固定在 GCHandle 上。相应地将 memcmp() 参数声明为 IntPtr 而不是 byte[]。

实际上可以工作的类型子集足够小,可以考虑简单地编写方法重载而不是泛​​型方法。现在使 pinvoke 编码器能够处理固定,相应地重载 memcmp() 函数声明。

关于c# - 如何将 fixed 与 Array 或 T[] 类型的变量一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14833218/

相关文章:

c# - 20 位整数数学

c# - EF : detach vs. 预加载与 noTracking

javascript - 返回 Bool 到 AJAX 请求

c# - 了解不安全代码及其用途

c# - 使用 JSON.NET 和 NodaTime 从 JSON 反序列化 LocalTime 导致 NodaTime.Text.UnparsableValueException

html - 尝试做一个有背景的固定菜单

css - 响应式网站 : move header nav from top to bottom problems

javascript - 修复了某些滚动后 div 位于其他 div 内的问题

c# - 在 c# 中为 Vector256 准备数据的最快方法是什么?

java - 为什么这两种获取 boolean 值的方法会得到不同的结果?