需要帮助理解我的C#控制台应用程序中的动态菜单

时间:2014-07-06 17:27:53

标签: c# console-application

我正在尝试设计一个控制台应用程序,其中菜单是从某种数据结构生成的,每个菜单项都可以指定一个处理程序/操作(可能只是显示不同的菜单)。对不起,如果这听起来很复杂!

我在找出正确的方法时遇到了很多麻烦。这是我的第一个C#应用程序,我觉得我已经阅读了几个小时的代表,我仍然不确定我是否应该使用它们。

我有很多现有的代码,但我觉得如果我在尝试修复可能在基础上破坏的内容之前得到一些总体方向可能会更好。我会试着描述一下我要做的事情:

  • 有一个“菜单”类,由菜单标题和任意数量的菜单项组成。
  • 每个“MenuItem”由热键,描述和“指向处理程序的指针”组成。
  • 处理程序完成工作并返回菜单。

这是我对“处理程序”的指针,我遇到了麻烦。应该如何在MenuItem对象中表示此处理程序?如何从菜单提示中调用处理程序?我是以完全错误的方式解决这个问题吗?

希望这是有道理的:)

1 个答案:

答案 0 :(得分:1)

我认为代表们可能是一个很好的起点。首先,因为它们在C#中相当受欢迎,因为你开始学习C#,这可能是一个很好的做法。其次,使用委托来实现您的应用程序应该相当简单。

让我们考虑Action<T>Func<T>代表。第一个可以执行某些操作但不会返回任何值。第二个返回类型T的值。两个类型最多可以包含16个参数。基本上他们的主要行为是成为方法的占位符。

因此,让我们看看嵌入在您的应用程序上下文中的一些示例:

public class MenuItem<T>
{
    public string Description { get; set; }
    public char HotKey { get; set; }
    public Func<T> FirstHandler { get; set; }       // returns some value
    public Action<T> SecondHandler { get; set; }    // does not return any value

    // let's use this method to invoke the first handler
    public T DoSomething()
    {
        // this handler is of type Func<T> so it will return a value of type T
        return this.FirstHandler.Invoke();
    }

    // let's use this method to invoke the second handler
    public void DoSomethingElse(T input)
    {
        this.SecondHandler.Invoke(input);
    }
}

如果Func如果它有多个参数而不是最后一个参数是返回类型。其他是输入类型。因此,例如Func<int, char, string>将接受以intchar作为输入但返回string的方法。您可以从Visual Studio获得一些帮助 - 在代理说明中,它在参数前面显示inout个单词,以表示它是否是输入或输出参数。

现在,创建MenuItem类后,您可以通过以下方式使用它:

class Program
{
    // A method that takes no input arguments but returns string
    private static string ReturnHelloWorld()
    {
        return "Hello World";
    }

    static void Main(string[] args)
    {
        MenuItem<string> menuItem = new MenuItem<string>();

        // FirstHandler signature is Func<T>
        // So it doesn't take any input arguments
        // and returns T - in our case string
        menuItem.FirstHandler = ReturnHelloWorld;

        // SecondHandler signature is Action<T>
        // So it takes one input argument of type T (here, string)
        // and returns void
        menuItem.SecondHandler = Console.WriteLine;

        // Now use a method of MenuItem class to invoke FirstHandler.
        string menuItemMessage = menuItem.DoSomething();
        // Use another method to invoke SecondHandler.
        menuItem.DoSomethingElse(menuItemMessage);
    }
}

请注意,它只是您问题的一个非常基本的起点。但它允许您创建菜单项并为项目分配不同的行为。