c# - 为什么 .Clear() 函数清除了错误的列表?
问题描述
public void ConvertMoves()
{
for (int i = 0; i < maxDirections; i++)
{
Debug.Log("gimme tsMoves "+tSpossibleMoves[i].Count + " from " + this);
possibleAttacks[i] = tSpossibleAttacks[i];
possibleAttacksInactive[i] = tSpossibleAttacksInactive[i];
possibleAttackIndicators[i] = tSpossibleAttackIndicators[i];
possibleMoves[i] = tSpossibleMoves[i];
Debug.Log("Gimme moves(1) " + possibleMoves[i].Count + " from " + this);
}
for (int i = 0; i < maxDirections; i++)
{
tSpossibleAttacks[i].Clear();
tSpossibleAttacksInactive[i].Clear();
tSpossibleAttackIndicators[i].Clear();
tSpossibleMoves[i].Clear();
Debug.Log("Gimme moves(2) " + possibleMoves[i].Count + " from " + this);
}
}
因此调试日志报告以下内容:
Gimme tsMoves 2 from JeanArc(Clone) (JeanArc)
Gimme move(1) 2 from JeanArc(Clone) (JeanArc)
到目前为止一切都很好,但是......
Gimme move(2) 0 from JeanArc(Clone) (JeanArc)
为什么它会清除整个不同 List 变量的动作?
解决方案
这不会创建列表项的副本:
possibleAttacks[i] = tSpossibleAttacks[i]
它只是简单地将同一个对象的引用复制到第二个变量中,因此possibleAttacks[i]
现在tSpossibleAttacks[i]
两者都指向内存中的同一个项目。可以将其想象为拥有两张信用卡来访问一个银行帐户。
您可以在 Microsoft 的文档中阅读有关引用类型的更多信息。
正如 Heinzi 在下面的评论中指出的那样,您可以通过调用来复制您的项目(因为它是一个列表):
possibleAttacks[i] = tSpossibleAttacks[i].ToList();
顺便说一句,如果您只想分配tSpossibleAttacks[i]
然后重置它,您也可以这样做:
possibleAttacks[i] = tSpossibleAttacks[i];
tSpossibleAttacks[i] = new List<your_type_name_here>(); // this will overwrite the reference held by `tSpossibleAttacks[i]`.
请注意,如果您的列表包含引用类型,那么您在列表中会遇到类似的问题,例如:
public class Test
{
public string Name { get; set; }
}
List<Test> list1 = new List<Test>();
list1.Add(new Test() { Name = "John" });
List<Test> list2 = list1.ToList();
Console.WriteLine(list1[0].Name); // John
Console.WriteLine(list2[0].Name); // John
list2[0].Name = "Fred";
Console.WriteLine(list1[0].Name); // Fred
Console.WriteLine(list2[0].Name); // Fred
所以我建议阅读值类型与引用类型以及引用在 C# 中的工作方式。
推荐阅读
- python - 熊猫:表的一部分方法的首选顺序
- kotlin - 在泛型类中创建具有 initialCapacity 的泛型 ArrayList
- sql - SQL如何获取父母及其所有孩子和孩子的孩子......等
- javascript - 用于区分 ipad Air 2019 和 iPad Pro2020 的 CSS 媒体查询
- java - 如何强制 intellij 使用特定的 TLS 版本?
- smarty - Smarty 从字符串中删除最后一个字符,如果它是 '/'
- perl - 这是标准 Perl 语言构造还是自定义:open HANDLE, ">$fname"
- angular - 传递带有状态的数据是未定义的
- r - 将订单号添加到重复的行
- powershell - 从 Azure DevOps 获取 WorkItem