Взаимное содержание двух классов

Суть ситуации: я создаю игру, в которой есть персонажи(class Character), и есть разнообразные предметы(class Item), которые эти персонажи могут носить с собой. Но так же и есть предметы, из которых могут появится персонажи и мне нужно заранее знать, какой персонаж появится из конкретного предмета, учитывая, что появляющийся персонаж, так же может иметь какие-то предметы. Каким образом это реализовать?

Я пытался реализовать это так - есть два класса, необходимо, чтобы в первом классе содержался экземпляр второго, а во втором - экземпляр первого.

При такой реализации компилятор ругается на зацикленность:

public class Item
{
   int id;
   Character mob = new Character();
}

public class Character
{
   int name;
   Item charInventory = new Item();
}

Ответы (1 шт):

Автор решения: user7860670

В C# классы являются ссылочными типами и их экзепляры содержатся в куче. Соответственно поле в классе может содержать в себе только ссылку на экземпляр другого класса, а не сам экзепляр другого класса.

Далее, в приведенном коде компилятор справедливо ругается на зацикленность, так как при создании экзепляра Item при инициализации поля mob будет создан экземпляр Character, при создании экземпляра которого будет инициализировано поле charInventory и будет создан еще один экземпляр Item и т.д. Чтобы избавиться от этого достаточно просто разорвать рекурсию и не создавать экземпляры другого класса автоматически при инициализации поля, оставляя ссылку нулевой, либо делегируя создание экземпляра внешнему коду:

public class Item
{
    public int id;
    public Character? mob;

    public Item(int initial_id)
    {
        this.id = initial_id;
        this.mob = null;
    }
   
    public Item(int initial_id, Character initial_mob)
    {
        this.id = initial_id;
        this.mob = initial_mob;
    }
}

public class Character
{
    public int id;
    public Item? item;

    public Character(int initial_id)
    {
        this.id = initial_id;
        this.item = null;
    }
   
    public Character(int initial_id, Item initial_item)
    {
        this.id = initial_id;
        this.item = initial_item;
    }
}

class Program
{
    static void Main()
    {
        var empty_egg = new Item(0); // mob будет null 
        var chicken = new Character(1, empty_egg);
        var cage = new Item(2, chicken);
        var peon = new Character(3, cage);
    }
}

online compiler

→ Ссылка