【问题标题】:User object Input into List of Data用户对象输入数据列表
【发布时间】:2017-12-17 05:37:49
【问题描述】:

我有一个程序试图创建一个典型的汽水箱程序,用户可以从一个列表中选择并添加到一个 24 的数组中,以表示汽水箱。但我希望它在这里打印出对象列表,以在继续之前检查我的代码是否没有损坏。除了我不能让它打印出数据。我用 foror 循环试过了,但没有用

public class BeverageData
{
      public string Name { set; get; }
      public string Type { set; get; }
      public decimal Price { set; get; }
      public int Size { get; set; }
}

class Beverages : IEnumerable<BeverageData>
{
    public static void BeverageRun()
    {
        var crate = new List<BeverageData>();

        //Add some items to it
        var newBeverage= new BeverageData();
        newBeverage.Name = "Fanta";
        newBeverage.Price = 0.75M;
        newBeverage.Type = "Soda";
        crate.Add(newBeverage);

        crate.Add(new BeverageData() { Name = "Pepsi", Price = 0.25M, Type = "Soda" });

        //Prompting the user


        crate.Add(PromptUserForBeverage());

        foreach (var beverage in crate)
        {
            Console.WriteLine(beverage);
        }
    }

    public void RemoveBeverage(string name)
    {

        var beverages = (from i in _items where String.Compare(i.Name, name, true) == 0 select i).FirstOrDefault();

        if (beverages != null)
            _items.Remove(beverages);
    }
    public IEnumerator<BeverageData> GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    private readonly List<BeverageData> _items = new List<BeverageData>();

    static BeverageData PromptUserForBeverage()
    {
        var beverage = new BeverageData();

        Console.WriteLine("Enter name: ");
        beverage.Name = Console.ReadLine();

        beverage.Price = GetDecimal("Enter cost: ");

        Console.WriteLine("Enter type: ");
        beverage.Type = Console.ReadLine();

        return beverage;
    }

    static decimal GetDecimal(string message)
    {
        do
        {
            Console.WriteLine(message);
            var input = Console.ReadLine();

            decimal result;
            if (Decimal.TryParse(input, out result))
                return result;

            Console.WriteLine("Invalid number");
        } while (true);
    }
}

主类编辑:

public static object MyProperty
        {
            get { return beverages; }
            set { beverages = new Crate}
        }
        static void Main(string[] args)
        {
            //var beverages = new Crate();
            ShowMenu();
            // Wait for input before closing
            Console.WriteLine("\nDone!\nPress any key to exit...");
            Console.ReadKey();
        }
        public static void ShowMenu()
        {
            Console.WriteLine("[1] Add Bottle from existing list to Bottle Crate");
            Console.WriteLine("[2] Remove Bottle from Bottle Crate");
            Console.WriteLine("[3] Show Bottle Crate");
            Console.WriteLine("[4] Add Beverage to list");
            Console.WriteLine("[5] Remove Beverage from list");
            Console.WriteLine("[6] Sort Bottles in Bottle Crate");
            Console.WriteLine("[7] Sort Beverages in list");

            ConsoleKeyInfo info = Console.ReadKey();
            int selection;
            int.TryParse(info.KeyChar.ToString(), out selection);

            switch (selection)
            {
                case 1:
                    var numBevs = Math.Max(GetInt("How many beverages would you like to enter: "), 0);

                    for (int i = 0; i < numBevs; i++)
                    {
                        Console.WriteLine($"\nEnter beverage #{i + 1} info");
                        Console.WriteLine("-----------------------");
                        beverages.Add(Crate.GetBeverageFromUser());
                        Console.WriteLine("-----------------------\n");
                    }
                    numBevs = Math.Max(GetInt("How many would you like to be auto-added: "), 0);

                    for (int i = 0; i < numBevs; i++)
                    {
                        beverages.Add(Crate.GetRandomBeverage());
                    }
                    Console.WriteLine("-----------------------\n");
                    ShowMenu();
                    break;
                //case 2:
                //    Remove_Bottle();
                //    ShowMenu();
                //    break;
                case 3:
                    Console.WriteLine("\nHere are the contents of the crate:\n");
                    Console.ForegroundColor = ConsoleColor.Green;
                    beverages.PrintBeverages();
                    Console.ResetColor();
                    ShowMenu();
                    break;
                //case 4:
                //    BeverageRun();
                //    ShowMenu();
                //    break;
                //case 5:
                //    Remove_Beverage();
                //    ShowMenu();
                //    break;
                //case 6:
                //    Sort_Bottles();
                //    ShowMenu();
                //    break;
                //case 7:
                //    Sort_Beverages();
                //    ShowMenu();
                //    break;
                //case 8:
                //    Calc_Total();
                //    ShowMenu();
                //    break;
                case 9:
                    break;
                default:
                    ShowMenu();
                    break;
            }

        }
    }
}

【问题讨论】:

  • 您在哪里尝试打印数据,但没有成功?
  • 这是你的整个程序吗?你什么都没留下?
  • 这不是整个程序,它还有我省略的其他部分只是填充物,我称之为这个类。除了结构之外,程序的其他类或多或少什么都没有。我试图在这里打印数据 foreach (var List in new List()) { Console.WriteLine(List); }

标签: c# arrays list collections


【解决方案1】:
public static void BeverageRun()
{
    var crate = new List<BeverageData>();

    //Add some items to it
    var newBeverage= new BeverageData();
    newBeverage.Name = "Fanta";
    newBeverage.Price = 0.75M;
    newBeverage.Type = "Soda";

    crate.Add(newBeverage);
    crate.Add(new BeverageData() { Name = "Pepsi", Price = 0.25M, Type = "Soda" });

    //Prompting the user
    crate.Add(PromptUserForBeverage());

    foreach (var beverage in crate)
    {
        PrintBeverage(beverage);
    }
}

static string PrintBeverage(BeverageData beverage)
{
    Console.WriteLine("Name: " + beverage.Name + ", Price: $" + beverage.Price + ", Type: " + beverage.Type);
}

我假设您打算遍历您的 crate 列表。但是,这样做将打印饮料对象。不是饮料的价值。因此,如果您想查看饮料的价值,您可能必须更改它。

编辑

正如Ed Plunkett 所述,您也可以覆盖BeverageDataToString()。这样做看起来像这样。

public class BeverageData
{
    public string Name { set; get; }
    public string Type { set; get; }
    public decimal Price { set; get; }
    public int Size { get; set; }

    public override string ToString()
    {
        return "Name: " + Name + ", Price: $" + Price + ", Type: " + Type;
    }
}

在foreach循环中:

foreach (var beverage in crate)
{
    Console.WriteLine(beverage);
}

【讨论】:

  • 打印出来的都是我的命名空间+这个类文件。
  • 我在回答中提到了这一点。我对其进行了更新,为您提供了一个示例,说明如何打印对象的值而不是对象本身。
  • @JsonDork 你也可以覆盖BeverageDataToString()方法。
  • 啊。太棒了!这行得通,现在我有另一个问题。用户输入永远不会被保存,每次我输入一个新的用户输入的对象都会被删除,有没有办法让它们保留下来并让用户添加很多饮料?
  • 如果您想保存用户输入(我假设是来自 BeverageRun?),那么您应该将其添加到全局列表 _items 而不是本地列表 crate(目前是每次调用方法时都重新创建)
【解决方案2】:

问题是您将项目添加到本地列表 (crate) 而不是类级列表 (_items)。

您可能遇到的其他几个问题是您允许为饮料类型输入字符串,这意味着用户输入时可能会出现一些错误(有些人可能会说“苏打水”,有些人可能会说“流行” ,有些人可能会说“汽水”)。要解决此问题,您可以为此字段使用预定义类型的 enum

public enum BeverageType
{
    Soda,
    Juice,
    Water,
    Alcohol
}

public class Beverage
{
    public string Name { set; get; }
    public BeverageType Type { set; get; }
    public decimal Price { set; get; }
    public int Size { get; set; }

    public override string ToString()
    {
        return $"{Name} ({Type}) = {Price:C}";
    }
}

我注意到的另一件事是,您没有向箱子提供 Add 项目的方法,只向 Remove 它们提供方法,所以我在下面添加了该方法。我还添加了另一个 Remove 方法,该方法将删除一个 Beverage 类型,该类型现在从您原来的 move 方法中调用。

我们还遗漏了MaxCapacity 功能 - 你说一个箱子只能容纳 24 件物品,但我们并没有在任何地方强制执行。现在,当有人调用Add 方法时,如果箱子已满,它会显示一条消息,他们必须先删除一些东西。

我还将PrintItems方法从BeverageRun方法中分离出来,我将BeverageRun改为AddBeverageFromUser,因为我觉得它做的太多了——它添加了一些预定义的饮料,得到一个来自用户,然后打印出来。通常最好有一个方法只做一件事。

我还添加了一个名为 AddRandomBeverage 的方法,因此我们可以自动填充 crate,而无需强迫用户进行大量输入。

最后,我添加了GetStringGetBeverageType 方法,以补充您从用户那里获取强类型信息的GetDecimal 方法。

这是最终的Crate 类的结果:

class Crate : IEnumerable<Beverage>
{
    private readonly List<Beverage> crate = new List<Beverage>();
    private const int MaxItems = 24;
    private static readonly Random Rnd = new Random();

    public void Add(Beverage beverage)
    {
        if (crate.Count >= MaxItems)
        {
            Console.WriteLine("The crate is full. Please remove an item first!");
        }
        else
        {
            crate.Add(beverage);
        }
    }

    public void Remove(string name)
    {
        Remove(crate.FirstOrDefault(i =>
            i.Name.Equals(name, StringComparison.OrdinalIgnoreCase)));
    }

    public void Remove(Beverage beverage)
    {
        if (crate.Contains(beverage)) crate.Remove(beverage);
    }

    public void PrintBeverages()
    {
        if (crate.Count == 0)
        {
            Console.WriteLine("There are no items in the crate.");
        }
        else
        {
            crate.ForEach(Console.WriteLine);
        }
    }

    public IEnumerator<Beverage> GetEnumerator()
    {
        return crate.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public static Beverage GetBeverageFromUser()
    {
        return new Beverage
        {
            Name = GetString("Enter name: "),
            Price = GetCurrency("Enter cost: "),
            Type = GetBeverageType("Enter type: ")
        };
    }

    public static Beverage GetRandomBeverage()
    {
        var names = new List<Beverage>
        {
            new Beverage {Name = "Coke", Price = .75m,
                Size = 12, Type = BeverageType.Soda},
            new Beverage {Name = "Pepsi", Price = .75m,
                Size = 12, Type = BeverageType.Soda},
            new Beverage {Name = "Sprite", Price = .75m,
                Size = 12, Type = BeverageType.Soda},
            new Beverage {Name = "Rootbeer", Price = .75m,
                Size = 12, Type = BeverageType.Soda},
            new Beverage {Name = "Orange Juice", Price = .5m,
                Size = 10, Type = BeverageType.Juice},
            new Beverage {Name = "Apple Juice", Price = .5m,
                Size = 10, Type = BeverageType.Juice},
            new Beverage {Name = "Grape Juice", Price = .5m,
                Size = 10, Type = BeverageType.Juice},
            new Beverage {Name = "Water", Price = .25m,
                Size = 20, Type = BeverageType.Water},
            new Beverage {Name = "Beer", Price = 2.75m,
                Size = 16, Type = BeverageType.Alcohol},
            new Beverage {Name = "Wine", Price = 3.5m,
                Size = 9, Type = BeverageType.Alcohol},
        };

        return names[Rnd.Next(names.Count)];
    }

    private static BeverageType GetBeverageType(string message)
    {
        BeverageType beverageType;

        Console.Write(message);

        while (!Enum.TryParse(Console.ReadLine(), true, out beverageType))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Invalid beverage type");
            Console.ResetColor();
            Console.Write("Valid beverage types are: ");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(string.Join(", ", Enum.GetNames(typeof(BeverageType))));
            Console.ResetColor();
            Console.Write(message);
        }

        return beverageType;
    }

    private static string GetString(string message)
    {
        Console.Write(message);
        return Console.ReadLine();
    }

    private static decimal GetCurrency(string message)
    {
        decimal result;
        Console.Write(message);

        while (!decimal.TryParse(Console.ReadLine(), NumberStyles.Currency, 
            CultureInfo.CurrentCulture, out result))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Invalid number");
            Console.ResetColor();
            Console.Write(message);
        }

        return result;
    }
}

用法

Crate 类的用法可能如下所示:

private static void Main()
{
    var beverages = new Crate();

    var numBevs = Math.Max(GetInt("How many beverages would you like to enter: "), 0);

    for (int i = 0; i < numBevs; i++)
    {
        Console.WriteLine($"\nEnter beverage #{i + 1} info");
        Console.WriteLine("-----------------------");
        beverages.Add(Crate.GetBeverageFromUser());
        Console.WriteLine("-----------------------\n");
    }

    numBevs = Math.Max(GetInt("How many would you like to be auto-added: "), 0);

    for (int i = 0; i < numBevs; i++)
    {
        beverages.Add(Crate.GetRandomBeverage());
    }
    Console.WriteLine("-----------------------\n");

    Console.WriteLine("\nHere are the contents of the crate:\n");
    Console.ForegroundColor = ConsoleColor.Green;
    beverages.PrintBeverages();
    Console.ResetColor();

    // Wait for input before closing
    Console.WriteLine("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

private static int GetInt(string message)
{
    int result;
    Console.Write(message);

    while (!int.TryParse(Console.ReadLine(), out result))
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Invalid number");
        Console.ResetColor();
        Console.Write(message);
    }

    return result;
}

输出

【讨论】:

  • 使用代码时,主类中的 GetInt 会生成无上下文错误。我们不需要在 crate 类中添加一个额外的方法吗?
  • 是的,我在主课上有这个,但没有包括它。我现在用GetInt 方法更新了答案,还稍微更新了Crate 类——为输出添加了一些颜色。 :)
  • _items 是全球性的吗?
  • 我以为你指的是private readonly List&lt;BeverageData&gt; _items = new List&lt;BeverageData&gt;();
【解决方案3】:

您正试图打印出一个新创建的列表中的项目(零项目)。不出所料,没有打印任何内容。

【讨论】:

  • 您将项目添加到本地声明的“板条箱”中,但随后正尝试遍历另一个新列表()。上面 Jun 的回答演示了您可能想要做的事情: foreach (var item in crate) { Console.WriteLine(item); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-12
  • 2018-01-07
  • 2021-03-11
  • 2021-12-31
  • 2020-11-17
相关资源
最近更新 更多