【问题标题】:Why string Method(Object object) may not match Func<Object, string> delegate type?为什么 string Method(Object object) 可能与 Func<Object, string> 委托类型不匹配?
【发布时间】:2019-10-17 12:29:43
【问题描述】:

我正在编写一个简单的基于控制台的菜单系统,作为 C# 课程项目的一部分,其中菜单的每个项目都包含一个匹配用户输入的字符串和一个要执行的命令。

public class MenuItem
    {
        private string _description;

        public string Description
        {
            get => _description;
            set => _description = Validate(value, 1, 100, false);
        }

        public Func<string> CommandToExecute { get; set; } // works

        public Func<Game, string> SaveCommand { get; set; } // refuses to work

    }

我尝试使用Func&lt;string&gt; 来模板静态字符串方法,并且效果很好。但是,现在我需要另一个 Func 来匹配将 Game 对象作为输入参数并返回字符串的方法。

不幸的是,当我尝试使用Func&lt;Game, string&gt; SaveCommand 匹配我的方法static string SaveGame(Game game) 时,程序将其标记为错误。

static string SaveGame(Game game)
        {
            var gameName = Console.ReadLine();

            ...
            return gameName;
        }

我将这个方法调用如下:

static string GameRun()
        {
            var game = new Game(_settings);

            var gameInnerMenu = new Menu(0)
                {
                    MenuTitle = "Choose one of the following actions:",
                    MenuItemsDictionary = new Dictionary<string, MenuItem>()
                    {
                        {
                            "S", new MenuItem()
                            {
                                Description = "Save the current game",
                                CommandToExecute = SaveGame(game)
                            }
                        }
                    }
                };

这段代码给了我一个错误Cannot convert source type 'string' to target type 'System.Func&lt;GameEngine.Game, string&gt;'

总的来说,我对 C# 和 OOP 非常陌生,所以如果我能就可能导致它的原因以及如何修复它,我将不胜感激。

【问题讨论】:

  • 当你创建新的Menu(0)时,使用CommandToExecute = SaveGame(现在不要传参数game,你只是分配方法..,当你使用它时,你将使用menu.xxx。 CommandToExecute(游戏)
  • 啊哈,这解释了错误,谢谢!但在这种情况下,如何将调用绑定到菜单?因为目前我正在将用户输入与字典匹配并通过运行菜单执行相应的命令。
  • 我不知道你程序的整个逻辑,但是,我想你使用“gameInnerMenu” 1)显示菜单的内容...... 2)在你的主循环或介绍状态循环(或者无论如何),你有一个监听器或键盘处理程序,当你抓住一个'S'键时,你在你的gameInnerMenu中搜索条目'S'并调用附加的方法。而这次使用 Game 参数。即:GameMenuItem gm=searchKey("S"); gm.CommandToExecute(游戏)。 CommandToExecute 是... SaveGame 的代表。对于键“Q”,您将拥有一个 CommandToExecute 以及 QuitGame 方法的委托等...
  • 非常感谢!我终于明白了,我只是让我的任务过于复杂,但了解那里到底发生了什么真的很有帮助

标签: c# delegates type-conversion func method-call


【解决方案1】:

问题是您没有将SaveGame 方法分配给CommandToExecute 属性。通过使用CommandToExecute = SaveGame(game),您将改为执行SaveGame 方法并将返回值分配给CommandToExecute

你应该做的是

{
    ...
    CommandToExecute = SaveGame
}

如果要查的话,这个语法叫做方法组转换,是写CommandToExecute = new Func&lt;Game, string&gt;(SaveGame)的捷径。

【讨论】:

    猜你喜欢
    • 2019-09-29
    • 2016-04-08
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多