【问题标题】:Question about array shallow copy in C#关于C#中数组浅拷贝的问题
【发布时间】:2010-10-21 23:06:44
【问题描述】:

只是为了确保我正确理解了引用类型的浅表副本,并且我没有在这里构造巨大的内存泄漏:

// Adds text to the beginning of the log RTB
// Also keeps the log RTB trimmed to 100 lines
var lines = new string[rtbLog.Lines.Length + 1];
lines[0] = "text";
Array.Copy(rtbLog.Lines, 0, lines, 1, rtbLog.Lines.Length);

if (lines.Length > 100)
{
    Array.Resize(ref lines, 100);
}

rtbLog.Lines = lines;

这将首先将 refs 复制到 rtbLog.Lines 中的字符串到行中。然后它将行中的前 100 个引用复制到一个新的字符串数组中。

表示 rtbLog.Lines 最初引用的数组,最初由行(调整大小之前)引用的数组,最后是任何不包含在行中的字符串(调整大小之后),都​​会被垃圾收集。 (我希望这是有道理的)

正确吗?

【问题讨论】:

    标签: c# arrays string shallow-copy


    【解决方案1】:

    Array.Resize 方法有点用词不当。它应该真正命名为 CopyToNewArrayWithSize。在后台,此 API 将创建一个新数组并将指定的数据复制到该数组中。然后通过引用返回新数组。

    关于垃圾回收。通过将 Lines 属性重置为新数组,您确实成功地删除了对数组的原始引用。只要没有对数组的其他引用,它就会在将来的某个时候被垃圾回收。

    【讨论】:

    • 一个“是”就足够了,但感谢您花时间以不同的方式解释! :) 只要我最后“弹出”的字符串得到 GC 处理(当然,前提是它们没有在其他地方引用),我很高兴。
    【解决方案2】:

    是的,不再使用的原始数组和字符串被垃圾回收就好了。

    如果您在创建数组之前计算出所需的大小,则不必调用 Resize(因为这将创建数组的另一个副本)。

    // Adds text to the beginning of the log RTB
    // Also keeps the log RTB trimmed to 100 lines
    int size = Math.Min(rtbLog.Lines.Length + 1, 100);
    string[] lines = new string[size];
    lines[0] = "text";
    Array.Copy(rtbLog.Lines, 0, lines, 1, size - 1);
    rtbLog.Lines = lines;
    

    【讨论】:

      猜你喜欢
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多