我正在编写一个小工具,从应用程序读取字节文件,更改字节文件中的值并保存新文件。在这个过程中,我遇到了 ForEach
循环中的一个行为,我无法解释。
我有一个 array list
,其中包含字节文件的自定义对象类型 (ExtendedHeader
) 的整理编号,现在我正在尝试批量编辑每个 ExtendedHeaders
如下
foreach (ExtendedHeader extendedHeader in extendedHeaders)
{
ExtendedHeader currentExtendedHeader = extendedHeader;
Console.Write(currentExtendedHeader.Time);
currentExtendedHeader.Time = 1;
currentExtendedHeader = extendedHeader;
Console.Write(currentExtendedHeader.Time);
}
WriteLine
的输出是 6 1
。 6 很好,因为它是 extendedHeader
对象中的默认值。但是,我不明白,为什么 extendedHeader
的每个实例都将其新值设置为 1,因为按照我的理解,我在循环中创建了每个 extendedHeader
实例的副本,称为 {{ 1}} 在任何时候都不会直接覆盖循环中的 currentExtendedHeader
实例(如果我是对的,这甚至不可能直接覆盖)。因此,在我将时间变量设置为 1 并用循环的 extendedHeader
覆盖 currentExtendedHeader
之后,我希望输出为 extendedHeader
。
我的逻辑在哪里?
答案 0 :(得分:3)
foreach
循环或变量赋值一般不会创建对象的副本。相反,它将引用传递给该变量 => 只有一个对象,但有多个指向该对象的指针。变量基本上只是内存中的一个地址,您可以让多个变量指向同一个地址,而无需创建对象副本。
答案 1 :(得分:0)
当您设置 currentExtenderHeader 时,您不是在制作对象的克隆。见https://docs.microsoft.com/en-us/dotnet/api/system.object.memberwiseclone?view=net-5.0。这是一种可以用来克隆对象的方法,但它并不完美。更好的方法是在对象上实现 ICloneable 接口:https://docs.microsoft.com/en-us/dotnet/api/system.icloneable?view=net-5.0 如果 ExtenderHeader 是您的对象之一。