如何使用LINQ在C#中根据用户输入显示另一个类的变量
问题描述
我接触C#仅两周,正在开发一个分两步的控制台计算器应用:
- 第一步:实现简单计算功能;
- 第二步:通过
Console.ReadLine()获取用户输入的选项(A/B/C),从MaterialRepo类的列表中匹配对应材料的名称与价格并展示。
目前卡在第二步,尝试用LINQ实现但失败了,求解决方案。
现有代码
Program.cs
using System; namespace Gutterjob { class Program { static void Main(String[] args) { Console.WriteLine("This is how much a gutter guard job will earn you!"); Console.WriteLine("---------"); Console.WriteLine("Step One:"); var maths = new Calculator(); maths.Main(); System.Threading.Thread.Sleep(1500); Console.WriteLine("---------"); Console.WriteLine("Step Two:"); Console.WriteLine("What type of gutter material are you using?"); Console.WriteLine("Gold - [A]"); Console.WriteLine("Silver - [B]"); Console.WriteLine("Tin foil - [C]"); //Have MaterialRepo data displayed here depending on user input. Console.ReadKey(); } } }
MaterialRepo.cs
using System; using System.Linq; using System.Collections.Generic; namespace Gutterjob { public class MaterialRepo { public string Id; public string? Metal; public string Price; List<MaterialRepo> matList = new List<MaterialRepo> { new MaterialRepo {Id = "A", Metal = "Gold", Price = "$4"}, new MaterialRepo {Id = "B", Metal = "Silver", Price = "$2"}, new MaterialRepo {Id = "C", Metal = "Tin Foil", Price = "$1"}, }; } }
解决方案
核心要解决两个问题:材料列表的外部访问权限和LINQ查询的正确实现,下面提供两种方案:
方案1:快速修改现有代码(适合新手)
直接调整MaterialRepo的列表为静态公共,让外部能访问,再用LINQ完成查询:
修改后的MaterialRepo.cs
using System; using System.Linq; using System.Collections.Generic; namespace Gutterjob { public class MaterialRepo { public string Id; public string? Metal; public string Price; // 将列表改为静态公共,允许外部直接访问 public static List<MaterialRepo> MatList = new List<MaterialRepo> { new MaterialRepo {Id = "A", Metal = "Gold", Price = "$4"}, new MaterialRepo {Id = "B", Metal = "Silver", Price = "$2"}, new MaterialRepo {Id = "C", Metal = "Tin Foil", Price = "$1"}, }; } }
补充Program.cs的第二步逻辑
在注释位置插入以下代码:
// 获取用户输入,去除空格并转为大写(兼容小写输入) string userInput = Console.ReadLine()?.Trim().ToUpper(); // 用LINQ的FirstOrDefault查询匹配的材料,找不到返回null var selectedMaterial = MaterialRepo.MatList.FirstOrDefault(m => m.Id == userInput); // 判断并输出结果 if (selectedMaterial != null) { Console.WriteLine($"你选择的材料:{selectedMaterial.Metal},价格:{selectedMaterial.Price}"); } else { Console.WriteLine("无效选项,请输入A/B/C中的一个"); }
方案2:更规范的代码结构(推荐)
把单个材料的实体和存储仓库分开,符合C#最佳实践,可读性更强:
新增Material实体类
namespace Gutterjob { // 单个材料的实体类,仅负责存储数据 public class Material { public string Id { get; set; } public string Metal { get; set; } public string Price { get; set; } } }
修改MaterialRepo为静态仓库类
using System; using System.Linq; using System.Collections.Generic; namespace Gutterjob { // 材料仓库类,负责管理材料数据 public static class MaterialRepo { // 只读的静态材料列表 public static List<Material> Materials { get; } = new List<Material> { new Material { Id = "A", Metal = "Gold", Price = "$4" }, new Material { Id = "B", Metal = "Silver", Price = "$2" }, new Material { Id = "C", Metal = "Tin Foil", Price = "$1" }, }; // 封装查询方法,外部调用更直观 public static Material GetMaterialById(string id) { // 忽略大小写匹配,提升用户体验 return Materials.FirstOrDefault(m => m.Id.Equals(id, StringComparison.OrdinalIgnoreCase)); } } }
补充Program.cs的第二步逻辑
// 获取用户输入 string userInput = Console.ReadLine()?.Trim(); // 调用仓库的方法获取材料 var selectedMaterial = MaterialRepo.GetMaterialById(userInput); // 输出结果 if (selectedMaterial != null) { Console.WriteLine($"材料:{selectedMaterial.Metal},价格:{selectedMaterial.Price}"); } else { Console.WriteLine("输入无效,请选择A/B/C"); }
关键说明
FirstOrDefault:LINQ方法,找到第一个匹配条件的元素,找不到时返回null,避免抛出异常;StringComparison.OrdinalIgnoreCase:忽略大小写匹配,用户输入小写a/b/c也能正常识别;- 拆分实体和仓库:让代码职责更清晰,后续扩展功能(比如添加材料)更方便。
内容的提问来源于stack exchange,提问作者AntMar
相关产品推荐
相关产品推荐

