功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案

原程序:

cs 复制代码
internal class ControllerParameterCreator : IParameterCreator
{
    private Controller controller;

    public ControllerParameterCreator(Controller controller)
    {
        this.controller = controller;
    }

    public Parameter CreateSystem(string name, int unused)
    {
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String),
            _ => null,
        };
    }

    public Parameter CreateAxis(string name, int index)
    {
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Axis, index),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Axis, index),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Axis, index),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Axis, index),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Axis, index),
            _ => null,
        };
    }

    public Parameter CreateTask(string name, int task)
    {
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Task, task),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Task, task),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Task, task),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Task, task),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Task, task),
            _ => null,
        };
    }
}

处理后程序:

cs 复制代码
internal class ControllerParameterCreator : IParameterCreator
{
    private Controller controller;

    public ControllerParameterCreator(Controller controller)
    {
        this.controller = controller;
    }

    public Parameter CreateSystem(string name, int unused)
    {
#if CSHARP_8_OR_NEWER
        // C# 8.0+ 递归模式写法
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String),
            _ => null,
        };
#else
        // C# 7.3 传统 switch 写法
        PrimitiveType type = ParameterInfoProvider.GetType(name);
        switch (type)
        {
            case PrimitiveType.Double:
                return new ControllerParameter<double>(controller, name, PrimitiveType.Double);
            case PrimitiveType.Integer:
                return new ControllerParameter<int>(controller, name, PrimitiveType.Integer);
            case PrimitiveType.Long:
                return new ControllerParameter<long>(controller, name, PrimitiveType.Long);
            case PrimitiveType.Single:
                return new ControllerParameter<float>(controller, name, PrimitiveType.Single);
            case PrimitiveType.String:
                return new ControllerParameter<string>(controller, name, PrimitiveType.String);
            default:
                return null;
        }
#endif
    }

    public Parameter CreateAxis(string name, int index)
    {
#if CSHARP_8_OR_NEWER
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Axis, index),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Axis, index),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Axis, index),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Axis, index),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Axis, index),
            _ => null,
        };
#else
        PrimitiveType type = ParameterInfoProvider.GetType(name);
        switch (type)
        {
            case PrimitiveType.Double:
                return new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Axis, index);
            case PrimitiveType.Integer:
                return new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Axis, index);
            case PrimitiveType.Long:
                return new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Axis, index);
            case PrimitiveType.Single:
                return new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Axis, index);
            case PrimitiveType.String:
                return new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Axis, index);
            default:
                return null;
        }
#endif
    }

    public Parameter CreateTask(string name, int task)
    {
#if CSHARP_8_OR_NEWER
        return ParameterInfoProvider.GetType(name) switch
        {
            PrimitiveType.Double => new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Task, task),
            PrimitiveType.Integer => new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Task, task),
            PrimitiveType.Long => new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Task, task),
            PrimitiveType.Single => new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Task, task),
            PrimitiveType.String => new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Task, task),
            _ => null,
        };
#else
        PrimitiveType type = ParameterInfoProvider.GetType(name);
        switch (type)
        {
            case PrimitiveType.Double:
                return new ControllerParameter<double>(controller, name, PrimitiveType.Double, ParameterContext.Task, task);
            case PrimitiveType.Integer:
                return new ControllerParameter<int>(controller, name, PrimitiveType.Integer, ParameterContext.Task, task);
            case PrimitiveType.Long:
                return new ControllerParameter<long>(controller, name, PrimitiveType.Long, ParameterContext.Task, task);
            case PrimitiveType.Single:
                return new ControllerParameter<float>(controller, name, PrimitiveType.Single, ParameterContext.Task, task);
            case PrimitiveType.String:
                return new ControllerParameter<string>(controller, name, PrimitiveType.String, ParameterContext.Task, task);
            default:
                return null;
        }
#endif
    }
}

关键实现说明

  1. 条件编译符号

    • 使用 #if CSHARP_8_OR_NEWER#else 隔离不同版本的语法。

    • 需在项目文件中定义符号(见下方配置步骤)。

  2. 版本差异处理

    • C# 8.0+ :使用简洁的递归模式匹配(switch 表达式)。

    • C# 7.3 :回退到传统的 switch-case 语句。

  3. 功能一致性

    两种写法的逻辑完全一致,仅语法形式不同。


项目配置步骤

  1. 定义编译符号

    .csproj 文件中根据语言版本自动设置符号:

cs 复制代码
<PropertyGroup>
  <!-- 当使用 C# 8.0+ 时自动定义符号 -->
  <DefineConstants Condition="'$(LangVersion)' >= '8.0'">CSHARP_8_OR_NEWER</DefineConstants>
</PropertyGroup>

手动指定版本(可选)

若需强制兼容性,可手动设置语言版本:

cs 复制代码
<PropertyGroup>
  <LangVersion>7.3</LangVersion> <!-- 或 8.0、latest 等 -->
</PropertyGroup>

优点

  • 无缝适配:根据项目语言版本自动选择最优语法。

  • 维护友好:升级到 C# 8.0+ 时无需修改代码,直接享受新语法。

  • 编译安全:避免因版本不兼容导致的编译错误。

相关推荐
飞人博尔特的摄影师17 分钟前
5分钟入门WPF和FluentValidation数据验证
经验分享·系统架构·c#·.net·wpf·.netcore
编程乐趣9 小时前
推荐一个Excel与实体映射导入导出的C#开源库
开源·c#·.net·excel
明月看潮生9 小时前
青少年编程与数学 02-020 C#程序设计基础 05课题、数据类型
开发语言·青少年编程·c#·编程与数学
o0向阳而生0o13 小时前
49、c# 能⽤foreach 遍历访问的对象需满足什么条件?
开发语言·c#·.net
智界工具库13 小时前
VPet虚拟桌宠,一款桌宠软件,支持各种互动投喂等. 开源免费并且支持创意工坊
c#·vpet
不想学习的奈何14 小时前
当前上下文中不存在名称“X509CertificateLoader”,编译.NET 9依赖
c#
徐赛俊15 小时前
Word VBA 教程|一键将 PNG/JPG 图片插入每一页(浮于文字上方,固定大小)
开发语言·c#·word
~小先生~15 小时前
设计模式——简单工厂模式
设计模式·c#·简单工厂模式