【问题标题】:Create a subarray reference in C# (using unsafe ?)在 C# 中创建子数组引用(使用不安全?)
【发布时间】:2010-04-08 08:59:41
【问题描述】:

我正在重构一个我们当前使用的库,我面临以下问题。

我们曾经有以下的东西:

class Blah
{
    float[][] data;
    public float[] GetDataReference(int index)
    {
        return data[index];
    }
}

由于各种原因,我已将这个锯齿状数组版本替换为一维数组版本,连接内部数组。 我的问题是:如何仍然返回对 data 子数组的引用?

class Blah
{
    float[] data;
    int rows;

    public float[] GetDataReference(int index)
    {
        // Return a reference data from offset i to offset j;
    }
}

我在想不安全和指针的东西可能有用,它可行吗?

【问题讨论】:

    标签: c# arrays multidimensional-array unsafe


    【解决方案1】:

    不,您不能这样做 - 但您应该考虑改用 ArraySegment

    请注意,数组对象由有关其长度等的元数据组成,然后是数据本身。如果您明白我的意思,您不能创建现有数组的切片并且仍然在数据旁边保留元数据 - 必须有一个额外的间接级别(这是ArraySegment 提供的)。

    (我有点惊讶 ArraySegment 没有做更多的包装,例如通过实现 IList<T>,但我们走了。如果你愿意,创建这样的结构很容易。)

    【讨论】:

    • 同意,我也不知道。我会保留我的答案(应该也可以),但这似乎是“正确的方式”(tm)
    • 锯齿状数组的内存布局使得使用不安全的结构来获取其内容是不切实际的。如果使用了多维数组,则可以在(罕见的)极端情况下使用多维数组,在这种情况下,多维数组的 .NET 性能对您来说太慢了。但是您仍然无法在不复制和添加新元数据的情况下返回切片。
    • @Abel:我理解它不是锯齿状的,只是一个长长的一维数组。想想你必须再次映射到行的 ImageData bytes[] 才能在指定的 x、y 处获得一些东西。至少我是这样得到他的。
    • 嗯,我已经用某种 IArray : IEnumerable 接口创建了一个包装器。效果很好,但意味着我必须更改/检查代码中对 GetDataReference 的所有调用......甚至一些我无法访问的代码......
    • 一个可以与数组互换使用的 ArraySegment 类会很棒,但需要 CLR 支持。支持索引运算符、IEnumerable 和扩大数组类型转换的 ArraySegment 和 ReadonlyArraySegment 结构也很不错。由于 ArraySegment 不支持任何东西,我不清楚它有什么用处。
    【解决方案2】:

    检查以下关于 SO 的问题,但不要使用已接受的答案(毕竟您不想复制),而是遵循使用 Enumerator 切片的其他选项/原始数组的子部分。

    Array slices in C#

    【讨论】:

      猜你喜欢
      • 2016-01-04
      • 1970-01-01
      • 2011-10-27
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-07-28
      • 2020-08-20
      • 2015-03-27
      相关资源
      最近更新 更多