C#如何通过继承构造函数枚举特定类型成员实现控制台菜单?
控制台菜单实现问题:无法枚举Option成员的解决方案需求
我正在为控制台制作菜单,编写了如下代码:
public class Option { /* Id, Name, & constructor */ } public abstract class Menu { protected const int rawId = 0; protected Menu() { int i = 0; // CS1579: foreach statement cannot operate on variables of type 'Menu.Menu' because 'Menu.Menu' does not contain a public instance definition for 'GetEnumerator' foreach (Option o in this) { o.Id = ++i; } // 为继承菜单中的每个选项分配ID } } public class MMain:Menu { Option OpenFile = new Option(rawId, "Open File"); Option ExitProgram = new Option(rawId, "Terminate Program"); public MMain():base() { } } int Prompt(/* menu to be displayed */) { /* 列出选项;返回选中的ID */ }
期望在主程序中能这样使用:
switch (Prompt(/* 此处为MMain实例 */)) { case MMain.OpenFile.Id: { /* 打开文件 */ break; } case MMain.ExitProgram.Id: { /* 退出程序 */ break; } }
问题在于foreach中的this需要实现GetEnumerator,我无法枚举基类和派生类中的Option成员,无Option时应至少返回空对象。
我希望避免:
- 在switch中使用字符串比较(影响效率,因此引入了id)
- 使用enum(尝试过,但无法作为函数参数,导致混乱)
- 为每个菜单定制函数(维护困难,破坏一致性)
是否有可行的实现方案?
失败的enum尝试(背景信息)
可忽略。若被建议尝试enum,我曾编写如下代码:
public class MMain { public enum Option { OpenFile, ExitProgram /* 更多选项 */ } public static string NameOf(Option o) { return o switch { Option.OpenFile => "Open File", Option.ExitProgram => "Terminate Program", _ => throw new ArgumentException(InvMO) }; } public static Option Prompt() { ListOptions(typeof(Option)); /* return Choice(...); */ } private static void ListOptions(Type t) { foreach (var option in Enum.GetValues(t)) { // CS1503: cannot convert from 'object' to 'Option' Console.WriteLine(NameOf(option)); /* 若尝试强制转换:Console.WriteLine((t)NameOf(option)) 会报错CS0118: 't' is a variable but is used like a type */ } } }
以及:
/* ... */ public static Option Prompt() { Option opts; ListOptions(opts); // 无法声明接收所有enum类型的函数 /* ... */
期望主程序中能这样使用:
switch (MMain.Prompt()) { case MMain.Option.OpenFile: { /* 打开文件 */ break; } case MMain.Option.ExitProgram: { /* 退出程序 */ break; } }
参考资料
我的代码参考了以下内容:
- 将枚举与字符串关联的C#实现思路
- 构造函数继承相关内容
对于enum尝试:
3. 泛型EnumLoop类实现思路(约束为struct和IConvertible)
4. 枚举值遍历的常规写法
5. 使用System.Type创建变量的相关思路
内容的提问来源于stack exchange,提问作者ThatHugo354
相关产品推荐
相关产品推荐

