Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C中的复制构造函数仍然保留其引用_C#_Winforms - Fatal编程技术网

C# C中的复制构造函数仍然保留其引用

C# C中的复制构造函数仍然保留其引用,c#,winforms,C#,Winforms,我目前正在用Windows窗体和C编写一个级别生成程序。每个级别都是从一系列“模式”创建的,这些模式在启动时加载到数组中。创建关卡时,程序将从该阵列中随机选择若干图案,随机旋转它们并创建关卡。选定的每个图案都存储在chosenPattern变量中,以便在不修改原始图案的情况下旋转 下面是我用来选择图案并旋转它的代码 int rand = randomNumber(0, patterns.Count - 1); Level chosenPattern

我目前正在用Windows窗体和C编写一个级别生成程序。每个级别都是从一系列“模式”创建的,这些模式在启动时加载到数组中。创建关卡时,程序将从该阵列中随机选择若干图案,随机旋转它们并创建关卡。选定的每个图案都存储在chosenPattern变量中,以便在不修改原始图案的情况下旋转

下面是我用来选择图案并旋转它的代码

int rand = randomNumber(0, patterns.Count - 1);                        
Level chosenPattern = new Level(patterns[rand]);
chosenPattern = rotatePattern(chosenPattern, randomNumber(0, 3));
下面是级别构造函数,包括复制构造函数

public class Level
    {
        public List<List<char>> grid;
        public string solution;
        public int difficulty;
        public TimeSpan generationTime;

        public Level()
        {
            grid = new List<List<char>>();
            solution = "";
            difficulty = 0;
            generationTime = TimeSpan.MinValue;
        }

        public Level(Level level)
        {
            grid = level.grid;
            solution = level.solution;
            difficulty = level.difficulty;
            generationTime = level.generationTime;
        }
    }
然而,即使在使用复制构造函数时,数组中存储的模式在旋转存储的模式时仍然是旋转的,我不确定为什么要注意:我是一个相当新手的C程序员

和RotatePattern函数:

 public Level rotatePattern(Level pattern, int rotation)
        {
            Level tempPattern = pattern;

            switch (rotation)
            {
                case 1:
                    //Rotate 90 - Reverse Each Row
                    for(int i = 0; i < tempPattern.grid.Count; i++)
                    {
                        tempPattern.grid[i].Reverse();
                    }
                    break;

                case 2:
                    //Rotate 180 - Reverse Each Row, then Each Column
                    for (int i = 0; i < tempPattern.grid.Count; i++)
                    {
                        tempPattern.grid[i].Reverse();
                    }

                    tempPattern.grid.Reverse();
                    break;

                case 3:
                    //Rotate 270 - Reverse Each Column
                    tempPattern.grid.Reverse();
                    break;
            }

            return tempPattern;
        }

在复制构造函数中,将其替换为

public Level(Level level)
{
     grid = level.grid.Select(x=>x.ToList()).ToList();
     solution = level.solution;
     difficulty = level.difficulty;
     generationTime = level.generationTime;
}
简单地传递列表将复制引用而不是值,这是因为网格属性与其他属性不同,不复制引用,因此复制的是地址而不是实际值

复制构造函数只是一个接受相同类型实例的构造函数。如果您指定给它的一个属性,即grid,那么如果该属性不是ValueType,那么您应该创建一个复制这些值的方法,使用grid=level.grid的纯赋值不会剪切它,并且会产生相同的结果

尝试将网格指定更改为以下内容:

grid = level.grid.Select(lst => lst.ToList()).ToList();

实际上,结构不是基本的,仍然可以通过值传递。列表是一个参考类型谢谢,我将把它改为ValueType而不是primitive。