为什么.Clear()函数清除错误的列表?

时间:2018-08-23 07:08:00

标签: c# list

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);
    }
}

因此,调试日志报告以下内容:

  

JeanArc(克隆)(JeanArc)的给定tsMoves 2
  Gimme从JeanArc(Clone)(JeanArc)移出(1)2

到目前为止一切都很好,但是然后...

  

Gimme将(2)0从JeanArc(Clone)(JeanArc)中移出

为什么要清除整个不同的List变量的移动?

2 个答案:

答案 0 :(得分:6)

这不会创建列表项的副本:

possibleAttacks[i] = tSpossibleAttacks[i]

它只是将 reference 复制到同一对象到另一个变量中,因此possibleAttacks[i]tSpossibleAttacks[i]现在都指向内存中的同一项目。可以想象这就像拥有两张信用卡来访问一个银行帐户一样。

您可以阅读有关参考类型here in Microsoft's docs的更多信息。

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#中的工作方式。

答案 1 :(得分:0)

@约翰说了什么。您需要复制列表。

for (int i = 0; i < maxDirections; i++)
{
    Debug.Log("gimme tsMoves "+tSpossibleMoves[i].Count +  " from " + this);
    possibleAttacks[i] = tSpossibleAttacks[i];
    tSpossibleAttacks[i] = new List<T>;

    possibleAttacksInactive[i] = tSpossibleAttacksInactive[i];
    tSpossibleAttacksInactive[i] = new List<U>();

    possibleAttackIndicators[i] = tSpossibleAttackIndicators[i];
    tSpossibleAttackIndicators[i] = new List<V>();

    possibleMoves[i] = tSpossibleMoves[i];
    tSpossibleMoves[i] = new List<Z>();

    Debug.Log($"Gimme moves(1), i={i}: {possibleMoves[i].Count} from {this}");
    Debug.Log($"Gimme moves(2)  i={i}: {tpossibleMoves[i].Count} from {this}");
}

示例:

var l1 = new List<string>();
List<string> l2;

l1.Add("One");
l1.Add("Two");

l2 = l1;
l1 = new List<string>();
l1.Add("Three");

Console.WriteLine("L1:");
foreach (var elem in l1)
{
    Console.WriteLine(elem);
}
Console.WriteLine("L2:");
foreach (var elem in l2)
{
    Console.WriteLine(elem);
}

此打印:

L1:
Three
L2:
One
Two