如何在不复制 C# 的情况下将结构数组元素提取到变量中?

Posted

技术标签:

【中文标题】如何在不复制 C# 的情况下将结构数组元素提取到变量中?【英文标题】:How to extract a struct array element into a variable without copying in C#? 【发布时间】:2020-07-14 07:33:41 【问题描述】:

我对 C# 中的结构数组有一个小问题:假设我有一个结构 Foo

struct Foo

    public string S;
    public int X;
    ...
    ...

我有一个 Foo 数组: Foo[] arr = ...

在一种方法中,我经常使用arr[i],所以我想将它保存在一个局部变量中(i 的表达式也有点长):var f = arr[i]

现在,我的问题是我知道结构是值类型,这意味着像这样的赋值会导致复制。结构有点大(7 个字符串和一个布尔值),所以在这种情况下我宁愿避免复制。

如果我没记错的话,在不复制结构的情况下访问结构字段的唯一方法是直接使用数组:arr[i].Sarr[i].X,但这很快就会变得很烦人。我真的很想将数组元素保存在局部变量中,但我不想通过将其复制到变量中来浪费性能。

有没有办法制作类似引用变量(类似于 C++)以避免复制?如果不是,那我很好奇它是否是编译器优化的东西?

我应该如何处理这个元素?我可以将它放在局部变量中而不复制还是必须通过数组访问它以避免复制?

提前致谢。

【问题讨论】:

【参考方案1】:

您可以在 C# 7 及更高版本中使用 ref 局部变量来执行此操作:

using System;


public struct LargeStruct

    public string Text;
    public int Number;


class Test

    static void Main()
    
        LargeStruct[] array = new LargeStruct[5];

        // elementRef isn't a copy of the array value -
        // it's really the variable in the array
        ref LargeStruct elementRef = ref array[2];
        elementRef.Text = "Hello";

        Console.WriteLine(array[2].Text); // Prints hello
    

当然,我通常建议避免:

大型结构 可变结构 公共字段(尽管如果它是可变的,最好通过公共字段来实现)

...但我承认总有例外。

【讨论】:

谢谢。我使用这个结构将数据存储在 Unity 项目中。这就是我必须使用可变公共字段的原因。至少,结构是私有的,所以我不在乎。

以上是关于如何在不复制 C# 的情况下将结构数组元素提取到变量中?的主要内容,如果未能解决你的问题,请参考以下文章