在我的研究中,我读到结构是值类型,因此复制结构的更改不会更改原始类型,而不是类。这是我想要和期望的行为。但是,在下面的最小代码示例中,很明显,复制结构中的更改反映回原始 - 对列表和数组都是如此。这是一个简单的WFA
,有一个按钮供您测试。复制结构中字段的修改会改变原始结构字段
这是怎么发生的?我read,这可能发生在传递结构作为数组成员时,我不这样做,我发现在类似的主题上的其他问题不显示此行为。如果有任何重复或相关的问题,我没有找到它们,并会感谢提示如何在将来找到它们。
namespace TestingStructs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
struct SingleLevel
{
public int Level { get; }
public int Property1 { get; }
public decimal Property2 { get; }
public SingleLevel(
int level,
int prop1,
decimal prop2)
{
Property1 = prop1;
Property2 = prop2;
Level = level;
}
}
struct Levels
{
public int NumberOfLevels { get; }
public readonly List<SingleLevel> RightLevels;
public readonly SingleLevel[] RightLevelsArray;
public Levels(int numberofLevels)
{
NumberOfLevels = numberofLevels;
RightLevels = new List<SingleLevel>();
RightLevelsArray = new SingleLevel[numberofLevels + 1];
for (int i = 1; i <= 3; i++)
{
SingleLevel rightToAdd = new SingleLevel(i, i * 100, 10 + i);
RightLevels.Add(rightToAdd);
RightLevelsArray[i - 1] = rightToAdd;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Levels lastLevels = new Levels(3);
Levels temporaryLevels = lastLevels;
MessageBox.Show("temp");
MessageBox.Show(string.Join(Environment.NewLine, temporaryLevels.RightLevels.Select(right => right.Property2)));
MessageBox.Show(string.Join(Environment.NewLine, temporaryLevels.RightLevelsArray.Select(right => right.Property2)));
MessageBox.Show("last");
MessageBox.Show(string.Join(Environment.NewLine, lastLevels.RightLevels.Select(right => right.Property2)));
MessageBox.Show(string.Join(Environment.NewLine, lastLevels.RightLevelsArray.Select(right => right.Property2)));
SingleLevel rightLevelToAdd = new SingleLevel(1, 50, 9.5m);
temporaryLevels.RightLevels.Insert(0, rightLevelToAdd);
temporaryLevels.RightLevelsArray[0] = rightLevelToAdd;
MessageBox.Show("temp after insert");
MessageBox.Show(string.Join(Environment.NewLine, temporaryLevels.RightLevels.Select(right => right.Property2)));
MessageBox.Show(string.Join(Environment.NewLine, temporaryLevels.RightLevelsArray.Select(right => right.Property2)));
MessageBox.Show("last after insert");
MessageBox.Show(string.Join(Environment.NewLine, lastLevels.RightLevels.Select(right => right.Property2)));
MessageBox.Show(string.Join(Environment.NewLine, lastLevels.RightLevelsArray.Select(right => right.Property2)));
}
}
}
输出:在插入后的temp和last包含与Property2非常相同的值。
背景:在我的代码中,我使用了一个对象实例,该对象实例在运行时可能会被修改,也可能不会被修改。因此,我想复制它,修改副本,然后可能将其等回到原始对象。如果不是这样,我不想改变原文,因此不会将任何阶段的修改应用到原文。设计可能有缺陷,问题是关于结构问题。不过,如果您对此有任何提示,我将不胜感激。
好的..我该如何改变它?我没有看到自己为了我的目的而使用与列表不同的集合,我需要能够复制它们并单独修改。你有什么建议吗? – pun11
我编辑了我的原始答案并添加了一个可能的解决方案。 –