将Spectre.Console CLI入门示例从C#转F#出现类型不兼容错误如何解决
问题原因
- 使用
AddBranch<AddSettings>定义分支后,分支要求所有子命令的设置类型必须兼容AddSettings。F#的泛型类型校验规则比C#更严格,仅指定命令类型的AddCommand重载无法自动识别命令关联的设置类型继承自AddSettings,因此触发ICommandLimiter<AddSettings>类型不兼容错误。 - 额外存在参数位置冲突问题:父类
AddSettings已经占用了索引为0的参数位置,子类AddPackageSettings、AddReferenceSettings再次将参数索引设为0,运行时会抛出参数重复错误。
修复方案
修改两处即可正常编译运行:
- 调用
AddCommand时使用双泛型参数重载,显式指定命令类型和对应的设置类型,同时添加|> ignore忽略方法返回值避免编译警告 - 调整子类参数的索引值为1,避免和父类的参数位置冲突
修改后完整代码如下:
open System open Spectre.Console.Cli type AddSettings() = inherit CommandSettings() [<CommandArgument(0, "[PROJECT]")>] member val Project = "" with get, set type AddPackageSettings() = inherit AddSettings() [<CommandArgument(1, "<PACKAGE_NAME>")>] member val PackageName = "" with get, set [<CommandOption("-v|--version <VERSION>")>] member val Version = "" with get, set type AddReferenceSettings() = inherit AddSettings() [<CommandArgument(1, "<PROJECT_REFERENCE>")>] member val ProjectReference = "" with get, set type AddPackageCommand() = inherit Command<AddPackageSettings>() override _.Execute (context, settings) = // 可替换为实际业务逻辑 printfn $"安装包:{settings.PackageName},所属项目:{settings.Project}" 0 type AddReferenceCommand() = inherit Command<AddReferenceSettings>() override _.Execute(context, settings) = printfn $"添加项目引用:{settings.ProjectReference},所属项目:{settings.Project}" 0 [<EntryPoint>] let main argv = let app = CommandApp() app.Configure(fun config -> config.AddBranch<AddSettings>("add", fun add -> add.AddCommand<AddPackageCommand, AddPackageSettings>("package") |> ignore add.AddCommand<AddReferenceCommand, AddReferenceSettings>("reference") |> ignore ) ) app.Run(argv)
内容的提问来源于stack exchange,提问作者Kurt Mueller
相关产品推荐
相关产品推荐

