创建一个包含元组的列表的列表。

huangapple go评论72阅读模式
英文:

creating a list of lists of tuples

问题

以下是翻译好的部分:

首先,这是我的第一个Stack Overflow请求,如果我的解释不够清楚,我很抱歉。

我现在正在使用C#开发一个游戏。目前它可以正常运行,所以我正在寻找的解决方案不是必需的,但我真的想简化我的代码的一部分。

我的代码如下:

我有一个名为Item的基类。

public class Item
{
    string name;
    //还有其他属性
}

我从这个类继承了多个不同的子类,看起来像这样:

public class TestItem : Item
{
    //属性
}

public class AnotherItem : Item
{
    //属性
}

现在,问题来了:

我的商店当前的代码看起来像这样:

ShopInventory shopInventory;
foreach ((AnotherItem item, int price) in shopInventory.anotherItems) 
{
    //以特定方式显示物品
}
foreach ((TestItem item, int price) in shopInventory.testItems)
{
    //以特定方式显示物品
}
//以此类推

这是一个方法中的代码,所以我们不需要全局变量,并且可以使用"var"等功能,正如你所看到的,它在重复自己。因此,我知道我可以缩短它:

shopInventory.testItems 是一个元组,看起来像这样:

public class ShopInventory
{
    public List<Tuple<TestItem, int>> testItems = new List<Tuple<TestItem, int>();
    //还有其他类似的
}

它显示了物品和价格。现在,我想创建一个包含这些列表的列表,以便我可以将上面的大部分显示部分缩短为如下形式:

foreach (var tempList in listOfLists)
{
    foreach ((var item, int price) in tempList)
    {
        //以特定方式显示物品
    }
}

我尝试了像下面这样的东西:

var listOfLists = new List<List<Tuple<Item, int>>();

或者

var listOfLists = new List<List<Tuple<object, int>>();

以及

var listOfLists = new List<List<Tuple<dynamic, int>>();

但如果我现在尝试添加一个列表:

listOfLists.Add(shopInventory.testItems);

添加行会被标记为红色下划线。然而,如果我创建像下面这样的内容:

var listOfLists = new List<List<Tuple<AnotherItem, int>>();
listOfLists.Add(shopInventory.anotherItems);

它可以工作,但显然只能存储"AnotherItem"类型的对象。我还以为如果使用基类Item,就不应该出现问题,但是... 是的,计划不起作用。如果你考虑为什么他不只是将价格添加到物品本身,原因是因为物品本身也在玩家的库存中使用,因此不需要另一个表示价格的变量。我可以创建另一个类,比如ShopItem,但如果这样做,我就需要复制每个其他类并从中继承,我认为使用元组会更高效。我不想因为价格的原因而创建另外5个脚本。

如果你有任何想法,请告诉我。我在编程方面只是"可以",所以如果你有其他想法,我也期待听到。

英文:

So first of all this is my first stackoverflow pull so I am sorry if my explanation is shit.
So I am working on a game right now in c#. It also does work right now so the solution I am looking for isnt necessary, however I really would like to sum up a big part of my code.

The code is the following:

I have a baseclass called Item.

    public class Item
    {
        string name;
        //and more
    }

From this class I inherit multiple different classes
which looks smth like this:

    public class TestItem : Item
    {
        //stuff
    }

    public class AnotherItem: Item
    {
        //stuff
    }

And now to the problem:

My shop looks currently something like this:

    ShopInventory shopInventory;
    foreach ((AnotherItem item,int price) in shopInventory.anotherItems) 
    {
        //display item in a specific way
    }
    foreach ((TestItem item,int price) in shopInventory.testItems)
    {
        //display item in a specific way
    }
    //and so on

It is in a method so we dont need global variables and can use things like "var", and
as you can see it replicates itself. So I know I can shorten it:

shopInventory.testItems is a tuple which looks like this:

    public class ShopInventory{
    public List &lt;Tuple&lt;TestItem, int&gt;&gt;testItems = new List&lt;Tuple&lt;TestItem , int&gt;&gt;();
    //and
    public List &lt;Tuple&lt;AnotherItem, int&gt;&gt;anotherItems= new List&lt;Tuple&lt;AnotherItem , int&gt;&gt;();
    //and more..
}

which displays the Item and a price.
And now I would like to create a list of those lists so I can shorten the big displaying part from above to something like

        foreach (var tempList in listOfLists )
        {
                foreach ((var item, int price) in tempList)
                {
                    //display item in a specific way
                }
        }

I tried things like

    var listOfLists = new List&lt;List&lt;Tuple&lt;Item,int&gt;&gt;&gt;();
    //or 

    var listOfLists = new List&lt;List&lt;Tuple&lt;object,int&gt;&gt;&gt;();
    //and 
    var listOfLists = new List&lt;List&lt;Tuple&lt;dynamic,int&gt;&gt;&gt;();
     

but if I try to add a list now:

    listOfLists.Add(shopInventory.testItems);

the add line just gets red underlined.
however if I create something like:

    var listOfLists = new List&lt;List&lt;Tuple&lt;AnotherItem,int&gt;&gt;&gt;();
    listOfLists.Add(shopInventory.anotherItems);

It works, but I can obviously only store objects of type "AnotherItem" into it.
I also thought if I use the base class Item I shouldnt get any problems but .. yea didnt worked as planned.
If you think about "why doesnt he just add the prices to the item itself" well it is because the item itself is also used in the players inventory and therefore doesnt need another variable which represents its price. I could create another class like shopItem, however if I would do that I would need to duplicate every other class and inherit from it and I thought like.. using tuple would be more efficient.. and I dont need to do like 5 more scripts just because of a price.

If you have any ideas pls let me know. I am only "ok" in programming so if you have any other ideas I am also looking forward for it.

答案1

得分: 1

  1. 为什么商店有不同类型物品的单独列表?你想每次销售新类型的物品时都更改逻辑吗?使用一个统一的List<Item>类型的列表。

  2. 元组之间没有继承关系。这使得针对不同类型元组进行编程非常困难,无法统一不同元组类型的列表。只需将价格整合到Item类中,避免使用元组。

更好的结构:

public abstract class Item
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class TestItem : Item
{
    public string Test { get; set; }
}

public class AnotherItem : Item
{
    public Color Color { get; set; }
}

基于这个类层次结构,你可以声明商店的库存如下:

public class ShopInventory
{
    public List<Item> Items { get; } = new();
}

现在你可以使用以下方式循环:

foreach (Item item in shopInventory.Items) {
    Console.WriteLine($"{item.Name} at {item.Price:C} is a {item.GetType().Name}");
}

然后,你仍然可以使用筛选器来处理特定类型的物品:

foreach (AnotherItem item in shopInventory.Items.OfType<AnotherItem>()) {
    Console.WriteLine($"{item.Name} at {item.Price:C} has color {item.Color}");
}
英文:

You have several design problems here:

  1. Why does the shop have distinct lists for different types of items? Do you want to change your logic every time you are selling a new type of item? Use one single lists of type List&lt;Item&gt;.

  2. There is no inheritance between tuples. This makes it very hard to program against different types of tuples and impossible to unify lists of different tuple types. Simply integrate the price in the Item class and avoid tuples.

Better structure:

public abstract class Item
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class TestItem : Item
{
    public string Test { get; set; }
}

public class AnotherItem : Item
{
    public Color Color { get; set; }
}

Based on this class hierarchy, you can declare the shop inventory as:

public class ShopInventory
{
    public List&lt;Item&gt; Items { get; } = new();
}

And now you can loop with:

foreach (Item item in shopInventory.Items) {
    Console.WriteLine($&quot;{item.Name} at {item.Price:C} is a {item.GetType().Name}&quot;);
}

You can then still work on a specific type of item by using a filter:

foreach (AnotherItem item in shopInventory.Items.OfType&lt;AnotherItem&gt;()) {
    Console.WriteLine($&quot;{item.Name} at {item.Price:C} has color {item.Color}&quot;);
}

huangapple
  • 本文由 发表于 2023年3月7日 01:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75653926.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定