Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.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# 两个对象(一个在列表中<;gt;)共享相同的内存地址,即如果其中一个对象发生更改,它将更改列表中的另一个对象_C#_List_Object_Memory Address - Fatal编程技术网

C# 两个对象(一个在列表中<;gt;)共享相同的内存地址,即如果其中一个对象发生更改,它将更改列表中的另一个对象

C# 两个对象(一个在列表中<;gt;)共享相同的内存地址,即如果其中一个对象发生更改,它将更改列表中的另一个对象,c#,list,object,memory-address,C#,List,Object,Memory Address,我在这方面投入了大量的努力和研究,我被困住了。我尝试过复制构造函数、复制函数和Memberwise克隆函数,但这些似乎都不起作用。矩阵[0]中的元素不应更改,但是g1中的更改会更改 如果有人知道如何解决这个问题,请回复 我正在添加额外的文本,以便发布我的问题 class Game { public Game() { Card_ID = 1; EmptyMainMonsterZones = 5; Empty

我在这方面投入了大量的努力和研究,我被困住了。我尝试过复制构造函数、复制函数和Memberwise克隆函数,但这些似乎都不起作用。
矩阵[0]
中的元素不应更改,但是
g1
中的更改会更改

如果有人知道如何解决这个问题,请回复

我正在添加额外的文本,以便发布我的问题

class Game
    {
        public Game()
        {

        Card_ID = 1;

        EmptyMainMonsterZones = 5;
        EmptyExtraMonsterZones = 1;
        EmptySpellTrapZones = 5;

        LP = 8000;

        NormalSummons = 1;

        DrawnCards = 0;

        LastEvent = "";

        CardPool = new List<Card>();

        ScenarioSteps = new List<string>();
    }

    public Game(Game other)
    {
        Card_ID = other.Card_ID;

        EmptyMainMonsterZones = other.EmptyMainMonsterZones;
        EmptyExtraMonsterZones = other.EmptyExtraMonsterZones;
        EmptySpellTrapZones = other.EmptySpellTrapZones;

        LP = other.LP;

        NormalSummons = other.NormalSummons;

        DrawnCards = other.DrawnCards;

        LastEvent = other.LastEvent;

        //CardPool = new List<Card>(other.CardPool);

        CardPool = new List<Card>();

        foreach (Card c in other.CardPool)
        {
            CardPool.Add(c);
        }

        //ScenarioSteps = new List<string>(other.ScenarioSteps);

        ScenarioSteps = new List<string>();

        foreach (string s in other.ScenarioSteps)
        {
            ScenarioSteps.Add(s);
        }
    }

    public object Clone()
    {
        return this.MemberwiseClone();
    }

    int Card_ID;

    public int EmptyMainMonsterZones;
    public int EmptyExtraMonsterZones;
    public int EmptySpellTrapZones;

    public int LP;

    public int NormalSummons;

    public int DrawnCards;

    public string LastEvent;

    public List<Card> CardPool = new List<Card>();

    public List<string> ScenarioSteps = new List<string>();

    public void Init(string name,string location,string position = "-")
    {
        Card c = new Card(name);

        if(location == "Main Monster Zone")
        {
            c.SetLocation(location);
            EmptyMainMonsterZones--;
        }
        else if (location == "Extra Monster Zone")
        {
            c.SetLocation(location);
            EmptyExtraMonsterZones--;
        }
        else
        {
            c.SetLocation(location);
            c.SetPosition(position);
            c.SetCard_ID(Card_ID);
            Card_ID++;
            CardPool.Add(c);
        }
    }

    public void PrintScenarioSteps()
    {
        for(int i=0;i<ScenarioSteps.Count;i++)
        {
            Console.WriteLine(ScenarioSteps[i]);
        }
    }

    public void Print()
    {
        for(int i=0;i<CardPool.Count;i++)
        {
            if(!CardPool[i].IsLocation("No Location"))
            {
                Console.WriteLine("{0} ({1}) is in the {2}", CardPool[i].getName(), CardPool[i].getLevel(), CardPool[i].getLocation());
            }
        }
    }

    // Checks
    bool IsCanBeNormalSummoned(Card c)
    {
        if (c.IsLevelBelow(4) && c.IsLocation("Hand") && EmptyMainMonsterZones > 0 && NormalSummons > 0) return true;
        if (c.IsException("Normal Summon without Tribute") && c.IsLocation("Hand") && EmptyMainMonsterZones > 0 && NormalSummons > 0) return true;
        return false;
    }

    // Operations

    public bool NormalSummon(ref Card c)
    {
        if(IsCanBeNormalSummoned(c))
        {
            c.SetPreviousLocation(c.getLocation());
            c.NormalSummoned = true;
            c.SetLocation("Main Monster Zone");

            EmptyMainMonsterZones--;
            NormalSummons--;
            LastEvent = "Normal Summon";

            if(!c.Negated)
            {
                if(c.IsName("Fusilier Dragon, the Dual-Mode Beast"))
                {
                    c.SetAttack(c.getAttack()/2);
                    c.SetDefense(c.getDefense()/2);
                }
            }

            return true;
        }
        return false;
    }
}

class Program
{
    static List<Game> Matrix = new List<Game>();

    static void Main(string[] args)
    {
        Game Duel = new Game();

        Duel.Init("Level Eater", "Hand");
        Duel.Init("Junk Forward", "Hand");
        Duel.Init("Fusilier Dragon, the Dual-Mode Beast","Hand");

        Matrix.Add(Duel);

        Game g1 = new Game(Matrix[0]);

        Console.WriteLine("g1:");
        g1.Print();
        Console.WriteLine();

        Console.WriteLine("Matrix[0]:");
        Matrix[0].Print();
        Console.WriteLine();

        Card c1 = g1.CardPool[0];

        if (g1.NormalSummon(ref c1))
        {
            string s = "Normal Summon " + g1.CardPool[0].getName() + ".";
            g1.ScenarioSteps.Add(s);

            Console.WriteLine("After Normal Summon:");
            Console.WriteLine("g1:");
            g1.Print(); // Pointing to the same address!!!
            Console.WriteLine();

            Console.WriteLine("Matrix[0]:");
            Matrix[0].Print(); // This changes, too!!!
            Console.WriteLine();

            Matrix.Add(g1);
        }

        g1 = new Game(Matrix[0]);

        if (Matrix[0].CardPool[0].IsLocation("Main Monster Zone")) Console.WriteLine("Yes, but I shouldn't be changed!");
        if (g1.CardPool[0].IsLocation("Main Monster Zone")) Console.WriteLine("Yes!");

        Card c2 = g1.CardPool[1];

        if (g1.NormalSummon(ref c2))
        {
            string s = "Normal Summon " + g1.CardPool[1].getName() + ".";
            g1.ScenarioSteps.Add(s);

            g1.Print();
            Console.WriteLine();

            g1.CardPool[0].Print();
            Console.WriteLine();

            Matrix.Add(g1);
        }

        g1 = new Game(Matrix[0]);

        Card c3 = g1.CardPool[2];

        if (g1.NormalSummon(ref c3))
        {
            string s = "Normal Summon " + g1.CardPool[2].getName() + ".";
            g1.ScenarioSteps.Add(s);

            g1.Print();
            Console.WriteLine();

            Matrix.Add(g1);
        }

        Console.WriteLine("Matrix Count: " + Matrix.Count);

        Console.ReadKey();
     }
}
类游戏
{
公共游戏()
{
卡ID=1;
空位面积=5;
EmptyExtraMonsterZones=1;
空培根=5;
LP=8000;
正常值=1;
DrawnCards=0;
LastEvent=“”;
CardPool=新列表();
ScenarioSteps=新列表();
}
公共游戏(其他游戏)
{
Card_ID=other.Card_ID;
EmptyMainMonsterZones=其他。EmptyMainMonsterZones;
EmptyExtraMonsterZones=other.EmptyExtraMonsterZones;
EmptySpellTrapZones=other.EmptySpellTrapZones;
LP=其他.LP;
normal传票=其他。normal传票;
DrawnCards=其他。DrawnCards;
LastEvent=other.LastEvent;
//CardPool=新列表(other.CardPool);
CardPool=新列表();
foreach(其他卡池中的卡c)
{
增加(c);
}
//ScenarioSteps=新列表(其他.ScenarioSteps);
ScenarioSteps=新列表();
foreach(其他.scenario步骤中的字符串s)
{
场景步骤。添加;
}
}
公共对象克隆()
{
返回此.MemberwiseClone();
}
智能卡;
公共int空置区;
公共int EmptyExtraMonsterZones;
公共内特空佩利兹;
公共int LP;
公开传唤;
公共int DrawnCards;
公共事件;
public List CardPool=新列表();
公共列表场景步骤=新建列表();
public void Init(字符串名称、字符串位置、字符串位置=“-”)
{
卡c=新卡(名称);
如果(位置=“主怪物区域”)
{
c、 设置位置(位置);
空区--;
}
否则如果(位置=“额外怪物区域”)
{
c、 设置位置(位置);
清空附加区--;
}
其他的
{
c、 设置位置(位置);
c、 设置位置(位置);
c、 设置卡号(卡号);
卡迪德++;
增加(c);
}
}
public void PrintScenarioSteps()
{
for(inti=0;i0)返回true;
如果(c.IsException(“无贡物的普通召唤”)&&c.IsLocation(“手牌”)&&EmptyMainMonsterZones>0&&NormalNotification>0)返回true;
返回false;
}
//操作
公众传票(参考卡c)
{
如果(IsCanBeNormalSummoned(c))
{
c、 SetPreviousLocation(c.getLocation());
c、 正常召唤=真;
c、 设置位置(“主要怪物区域”);
空区--;
正常传票--;
LastEvent=“正常召唤”;
如果(!c.否定)
{
if(c.IsName(“Fussiler Dragon,双模式野兽”))
{
c、 SetAttack(c.getAttack()/2);
c、 SetDefense(c.getDefense()/2);
}
}
返回true;
}
返回false;
}
}
班级计划
{
静态列表矩阵=新列表();
静态void Main(字符串[]参数)
{
游戏决斗=新游戏();
决斗初始(“水平食客”,“手”);
决斗初始(“垃圾前进”,“手”);
决斗初始(“火龙,双模野兽”,“手”);
矩阵。添加(决斗);
游戏g1=新游戏(矩阵[0]);
控制台写入线(“g1:”);
g1.Print();
Console.WriteLine();
Console.WriteLine(“矩阵[0]:”);
矩阵[0]。打印();
Console.WriteLine();
卡c1=g1.卡池[0];
如果(g1.正常召唤(参考c1))
{
字符串s=“普通召唤”+g1.CardPool[0].getName()+”;
g1.场景步骤。添加;
控制台。书写线(“正常召唤后:”);
控制台写入线(“g1:”);
g1.Print();//指向同一地址!!!
Console.WriteLine();
Console.WriteLine(“矩阵[0]:”);
矩阵[0].Print();//这也会改变!!!
Console.WriteLine();
矩阵。添加(g1);
}
g1=新游戏(矩阵[0]);
if(矩阵[0].CardPool[0].IsLocation(“主怪物区域”))Console.WriteLine(“是的,但我不应该被改变!”);
if(g1.CardPool[0].IsLocation(“主怪物区域”))Console.WriteLine(“Yes!”);
卡c2=g1.卡池[1];
如果(g1.正常召唤(参考c2))
{
字符串s=“普通召唤”+g1.CardPool[1].getName()+”;
g1.场景步骤。添加;
g1.Print();
Console.WriteLine();
g1.CardPool[0].Print();
Console.WriteLine();
矩阵。添加(g1);
}
g1=新游戏(矩阵[0]);
卡c3=g1.卡池[2];
如果(g1.正常召唤(参考c3))
{
字符串s=“普通召唤”+g1.CardPool[2].getName()+”;
g1.场景步骤。添加;
g1.Print();
Console.WriteLine();
矩阵。添加(g1);
}
Console.WriteLine(“矩阵计数:+Matrix.Count”);
Console.ReadKey();
}
}

我建议使用一种方法来复制对象,而不是使用对另一个也会更新的对象的引用。您可以将此方法添加到可以为任何游戏对象调用的游戏类中

序列化对象会将其转换为字符串,然后反序列化将其更改回新对象(无需任何引用)
    public Game Clone(Game other)
    {
        return JsonConvert.DeserializeObject<Game>(JsonConvert.SerializeObject(other));
    }
Game g1 = new Game().Clone(Matrix[0]);
Game g1 = JsonConvert.DeserializeObject<Game>(JsonConvert.SerializeObject(Matrix[0]);
public object Clone()
{
    return this.MemberwiseClone();
}
Game g1 = new Game((Game)Matrix[0].Clone());
    static void Main(string[] args)
    {

            Game Duel = new Game();

            Duel.Init("Level Eater", "Hand");
            Duel.Init("Junk Forward", "Hand");
            Duel.Init("Fusilier Dragon, the Dual-Mode Beast", "Hand");

            Matrix.Add(Duel);

            Game g1 = new Game((Game)Matrix[0].Clone());

            Console.WriteLine("g1:");
            g1.Print();
            Console.WriteLine();

            Console.WriteLine("Matrix[0]:");
            Matrix[0].Print();
            Console.WriteLine();

            Card c1 = g1.CardPool[0];

            if (g1.NormalSummon(ref c1))
            {
                string s = "Normal Summon " + g1.CardPool[0].getName() + ".";
                g1.ScenarioSteps.Add("dsqdqdqdq");

                Console.WriteLine("After Normal Summon:");
                Console.WriteLine("g1:");
                g1.Print(); // Pointing to the same address!!!
                Console.WriteLine();

                Console.WriteLine("Matrix[0]:");
                Matrix[0].Print(); // This changes, too!!!
                Console.WriteLine();

                Matrix.Add(g1);
            }

            g1 = new Game((Game)Matrix[0].Clone());

            if (Matrix[0].CardPool[0].IsLocation("Main Monster Zone")) Console.WriteLine("Yes, but I shouldn't be changed!");
            if (g1.CardPool[0].IsLocation("Main Monster Zone")) Console.WriteLine("Yes!");

            Card c2 = g1.CardPool[1];

            if (g1.NormalSummon(ref c2))
            {
                string s = "Normal Summon " + g1.CardPool[1].getName() + ".";
                g1.ScenarioSteps.Add(s);

                g1.Print();
                Console.WriteLine();

                g1.CardPool[0].Print();
                Console.WriteLine();

                Matrix.Add(g1);
            }

            g1 = new Game((Game)Matrix[0].Clone());

            Card c3 = g1.CardPool[2];

            if (g1.NormalSummon(ref c3))
            {
                string s = "Normal Summon " + g1.CardPool[2].getName() + ".";
                g1.ScenarioSteps.Add(s);

                g1.Print();
                Console.WriteLine();

                Matrix.Add(g1);
            }

            Console.WriteLine("Matrix Count: " + Matrix.Count);

            Console.ReadKey();

    }

public class Game : ICloneable
{
    public Game()
    {

        Card_ID = 1;

        EmptyMainMonsterZones = 5;
        EmptyExtraMonsterZones = 1;
        EmptySpellTrapZones = 5;

        LP = 8000;

        NormalSummons = 1;

        DrawnCards = 0;

        LastEvent = "";

        CardPool = new List<Card>();

        ScenarioSteps = new List<string>();
    }

    public Game(Game other)
    {
        Card_ID = other.Card_ID;

        EmptyMainMonsterZones = other.EmptyMainMonsterZones;
        EmptyExtraMonsterZones = other.EmptyExtraMonsterZones;
        EmptySpellTrapZones = other.EmptySpellTrapZones;

        LP = other.LP;

        NormalSummons = other.NormalSummons;

        DrawnCards = other.DrawnCards;

        LastEvent = other.LastEvent;

        //CardPool = new List<Card>(other.CardPool);

        CardPool = new List<Card>();

        foreach (Card c in other.CardPool)
        {
            CardPool.Add(c);
        }

        //ScenarioSteps = new List<string>(other.ScenarioSteps);

        ScenarioSteps = new List<string>();

        foreach (string s in other.ScenarioSteps)
        {
            ScenarioSteps.Add(s);
        }
    }


    int Card_ID;

    public int EmptyMainMonsterZones;
    public int EmptyExtraMonsterZones;
    public int EmptySpellTrapZones;

    public int LP;

    public int NormalSummons;

    public int DrawnCards;

    public string LastEvent;

    public List<Card> CardPool = new List<Card>();

    public List<string> ScenarioSteps = new List<string>();

    public void Init(string name, string location, string position = "-")
    {
        Card c = new Card(name);

        if (location == "Main Monster Zone")
        {
            c.SetLocation(location);
            EmptyMainMonsterZones--;
        }
        else if (location == "Extra Monster Zone")
        {
            c.SetLocation(location);
            EmptyExtraMonsterZones--;
        }
        else
        {
            c.SetLocation(location);
            c.SetPosition(position);
            c.SetCard_ID(Card_ID);
            Card_ID++;
            CardPool.Add(c);
        }
    }

    public void PrintScenarioSteps()
    {
        for (int i = 0; i < ScenarioSteps.Count; i++)
        {
            Console.WriteLine(ScenarioSteps[i]);
        }
    }

    public void Print()
    {
        for (int i = 0; i < CardPool.Count; i++)
        {
            if (!CardPool[i].IsLocation("No Location"))
            {
                Console.WriteLine("{0} ({1}) is in the {2}", CardPool[i].getName(), CardPool[i].getLevel(), CardPool[i].getLocation());
            }
        }
    }

    // Checks
    bool IsCanBeNormalSummoned(Card c)
    {
        if (c.IsLevelBelow(4) && c.IsLocation("Hand") && EmptyMainMonsterZones > 0 && NormalSummons > 0) return true;
        if (c.IsException("Normal Summon without Tribute") && c.IsLocation("Hand") && EmptyMainMonsterZones > 0 && NormalSummons > 0) return true;
        return false;
    }

    // Operations

    public bool NormalSummon(ref Card c)
    {
        if (IsCanBeNormalSummoned(c))
        {
            c.SetPreviousLocation(c.getLocation());
            c.NormalSummoned = true;
            c.SetLocation("Main Monster Zone");

            EmptyMainMonsterZones--;
            NormalSummons--;
            LastEvent = "Normal Summon";

            if (!c.Negated)
            {
                if (c.IsName("Fusilier Dragon, the Dual-Mode Beast"))
                {
                    c.SetAttack(c.getAttack() / 2);
                    c.SetDefense(c.getDefense() / 2);
                }
            }

            return true;
        }
        return false;
    }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}