【问题标题】:Items in static List<Item>()静态 List<Item>() 中的项目
【发布时间】:2015-04-04 12:27:43
【问题描述】:

所以我有一个静态项目列表,其中存储了一些类,在这些类中是变量,例如“int ID”、“string name”、“string description”、“int currentAmount”等。

ItemDatabase.cs...

public static List<Item> Items

static void LoadItemData()
{
    Items.Add(new item);
    ...
}

然后我有一个单独的项目列表,其中将添加项目供玩家使用。

Player.cs...

List<Item> playerItems;

然后在其他类中,我有AddItem(int ID) 方法:

void AddItem(int id)
{
    foreach (Item i in ItemDatabase.Items)
        if (i.ID == id)
            playerItems.Add(i);
}

我目前正在添加将使用相同数据的实体。但是当我修改添加到 playerItems 的 Item 时,它会修改 ItemDatabase.Items (显然,由于引用)。

我不能将 Item 类变成一个结构,因为我还有其他派生自它的类。 我需要“currentAmount”整数按值计算。有什么办法可以做到吗?

P.S.,我已经尝试过深度克隆,但它与我的 Item 类不能很好地配合。

【问题讨论】:

  • 为什么克隆不起作用?似乎这就是解决方案。如果您只是修改值类型(string,int),您可以浅克隆吗?
  • @DStanley,我尝试进行深度克隆,在每个类的顶部插入 [Serializable] 属性,但是我无法控制的其他类(如 Texture2D)给了我这个。我在 Item 类中还有其他类。如果我不进行深拷贝,它们不会被设置为 null 吗?
  • 您不需要序列化来进行深度克隆 - 序列化和反序列化只是一种方式。如果您不更改引用类型,那么我只会做一个浅克隆(手动复制属性 vlaues 或使用 object.MemberwiseClone
  • @DStanley,非常感谢。我尝试了 MemberwiseClone,效果很好。你介意把它作为答案吗?

标签: c# reference pass-by-reference


【解决方案1】:

如果您想更改对象而不影响原始对象,显然您需要克隆对象。序列化是进行“深度克隆”的一种方法,但正如您所发现的,并非所有类型都可以序列化。

如果您只是修改一级值类型属性(不更改相关项的值或引用),您可以使用object.MemberwiseClone 创建一个副本(值类型和引用的副本) .

【讨论】:

    【解决方案2】:

    你需要分离出currentAmount。由于该值仅在 Player 的上下文中才有意义无论如何,我会将其从 Item 类中取出,并使用 Dictionary&lt;Item,int&gt; 来跟踪库存:

    Dictionary<Item, int> inventory = new Dictionary<Item, int>();
    
    void AddItem(int id)
    {
        foreach (Item i in ItemDatabase.Items)
            if (i.ID == id)
                playerItems.Add(i, 0); //Or whatever count
    }
    

    【讨论】:

      【解决方案3】:

      这样做:

      void AddItem(int id)
      {
          var item = ItemDatabase.Items.FirstOrDefault(x=> x.ID == id);
          if(item!=null){
              playerItems.Add(new Item(){ ID = item.ID, Name = item.Name, etc... })
          }
      }
      

      【讨论】:

        【解决方案4】:

        我仍然不确定您在哪里修改 ItemsDatabase.Items(currentAmount 作为实体的属性没有多大意义),但对于您库存中的当前数量,我想这会对您有所帮助:

        Dictionary<Item, int> inventory = new Dictionary<Item, int>();
        
        void AddItem(int id)
        {
            foreach (Item i in ItemDatabase.Items)
                if (i.ID == id)
                    {
                      if(!inventory.Keys.Contains(i)){iventory.Add(i, 0);}
                      inventory[i]+=1; //increment the amount of items in inventory.
                    }
        }
        

        重要:

        Dictionary 使用 Hash 从字典中获取对象,因此,您可能希望在 Item 类中覆盖该方法:

        class Item {
            public string Name;
            public string Description;
            public int currentAmount;
        
            public override int GetHashCode(){
               return Name.GetHashCode() + Description.GetHashCode();
            }
        }
        

        查看更多:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-09
          • 1970-01-01
          • 2020-07-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多