我的方法中的参数(list <t>)将被更改

时间:2017-01-18 11:33:29

标签: c# list pointers

我发送了一个对象列表List<solutions>&#34; _solutions&#34;作为参数的方法,然后我将此参数复制到另一个名为&#34; SOLUTIONS &#34;的列表中。并对SOLUTIONS进行一些更改,最后返回SOLUTIONS。但是当我更改SOLUTIONS时,_solution将被更改。我不想改变_solutions。   例如,在行SOLUTIONS[pp].Route.Clear();之后,当pp = 0时,_solution [0]。路径将会清晰。

static List<solutions> CrossOverB(List<solutions> _Solutions)
{
    List<solutions> SOLUTIONS = new List<solutions>();
    SOLUTIONS.AddRange(_Solutions);

    int pp = 0;
    List<int> Team1;
    List<int> Team2;

    List<int> TempOff1;
    List<int> TempOff2;
    int index1 = 0;
    double Time1 = int.MaxValue, Time2 = int.MaxValue;

    while (pp < PopulationSize)
    {
        Team1 = new List<int>();
        Team2 = new List<int>();
        TempOff1 = new List<int>();
        TempOff2 = new List<int>();
        index1 = 0;
        Time1 = int.MaxValue;
        Time2 = int.MaxValue;
        int[] MinMax = new int[2];

        int maxindex = 0, minindex = 0;
        MinMax = FindMaximumMinimumTeam(SOLUTIONS[pp].Route);
        minindex = MinMax[0];
        maxindex = MinMax[1];
        //extract maximum team from 
        Team1 = ExtractTeamFromSolution(SOLUTIONS[pp].Route, maxindex);
        //remove start and end city
        Team1.RemoveAt(0);
        Team1.RemoveAt(Team1.Count - 1);

        Team2 = ExtractTeamFromSolution(SOLUTIONS[pp].Route, minindex);
        Team2.RemoveAt(0);
        Team2.RemoveAt(Team2.Count - 1);
        //add team2 to team1
        //all cities are in team1
        Team1.AddRange(Team2);
        Team2.Clear();

        //add other teams(except max and min team) to the team2
        for (int i = 1; i < NoOfTeams + 1; i++)
        {
            if (i != maxindex && i != minindex)
            {
                Team2.AddRange(ExtractTeamFromSolution(SOLUTIONS[pp].Route, i));
            }
        }

        TempOff1.Add(StartCity);
        TempOff1.Add(endCity);
        TempOff2.Add(StartCity);
        TempOff2.Add(endCity);
        //index1 = TempOff1.Count - 1;
        //index2 = TempOff2.Count - 1;

        while (index1 != Team1.Count)
        {
            Time1 = int.MaxValue;
            Time2 = int.MaxValue;

            //fill off1
            //i want to add team1[index1] to the off1 or off2 righ befor the end city
            if (CalculateTeamTime(TempOff1, Team1.ElementAt(index1), TempOff1.Count - 2) < TMAX)
            {
                Time1 = TimeTable[TempOff1.ElementAt(TempOff1.Count - 2)][Team1.ElementAt(index1)];
            }
            if (CalculateTeamTime(TempOff2, Team1.ElementAt(index1), TempOff2.Count - 2) < TMAX)
            {
                Time2 = TimeTable[TempOff2.ElementAt(TempOff2.Count - 2)][Team1.ElementAt(index1)];
            }

            //compare time1 and time2 for the winner
            if (Time1 <= Time2 
                && TempOff1.Contains(Team1.ElementAt(index1)) == false 
                && TempOff2.Contains(Team1.ElementAt(index1)) == false  
                && Team2.Contains(Team1.ElementAt(index1)) == false
                && CalculateTeamTime(TempOff1, Team1.ElementAt(index1), TempOff1.Count - 2) < TMAX)//fill off1
            {
                TempOff1.Insert(TempOff1.Count - 1, Team1.ElementAt(index1));
                index1++;
            }
            else if (Time1 >= Time2 
                && TempOff2.Contains(Team1.ElementAt(index1)) == false 
                && TempOff1.Contains(Team1.ElementAt(index1)) == false  
                && Team2.Contains(Team1.ElementAt(index1)) == false
                && CalculateTeamTime(TempOff2, Team1.ElementAt(index1), TempOff2.Count - 2) < TMAX)//fill off2
            {
                TempOff2.Insert(TempOff2.Count - 1, Team1.ElementAt(index1));
                index1++;
            }
            else// off1 and off2 do not accept the city. so i reject the city
            {
                index1++;
            }// of else

            if (CalculateTeamTime(TempOff2)>TMAX)
            {
                Console.WriteLine();
            }

        }// of while

        SOLUTIONS[pp].Route.Clear();
        SOLUTIONS[pp].Route.AddRange(TempOff1);
        SOLUTIONS[pp].Route.AddRange(TempOff2);
        SOLUTIONS[pp].Route.AddRange(Team2);

        pp++;
    }

    return SOLUTIONS;
}

2 个答案:

答案 0 :(得分:1)

我猜solutions是一个班级,对吗?类是引用类型,即您不对实际对象进行操作,而是对这些对象的引用。

当您调用SOLUTIONS.AddRange(_Solutions);时,您并没有真正复制对象,但是您只是复制对_Solutions中对象的引用并将它们存储在SOLUTIONS中,但对象仍然存在同样的。 _Solutions中的第一个对象与<{1}}中的第一个对象完全相同(依此类推),而不是保存相同数据的不同对象。

您必须创建对象的深层副本才能解决此问题。例如,您可以在SOLUTIONS

中实现方法Copy
solutions

然后更改行以将项目复制到

solutions Copy()
{
    return new solutions
    {
    [... copy all fields here]
    };
}

您将拥有一个包含全新对象的全新列表,而不仅仅是旧列表中无聊的旧对象。

答案 1 :(得分:0)

您实际上正在复制对_Solutions列表中元素的引用。从_Solutions中的元素查询信息时,元素级别的任何更改(元素中的某些属性)也将可见。

您的代码

List<solutions> SOLUTIONS = new List<solutions>();
SOLUTIONS.AddRange(_Solutions);

只能确保你有一个不同的引用列表(当你想要迭代时可能很有用 - foreach - 并且在原始列表中进行更改,这是不能直接完成的。)

您已经深深克隆了您的列表,实际上正在为每个元素生成对象的新实例,正如bradbury9已建议的那样(检查here)。