功能“递归模式”在 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+ 时无需修改代码,直接享受新语法。

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

相关推荐
索迪迈科技19 小时前
记一次 .NET 某中医药附属医院门诊系统 崩溃分析
windows·c#·.net·windbg
SunflowerCoder19 小时前
WPF迁移avalonia之触发器
c#·wpf·avalonia
长安——归故李1 天前
【modbus学习】
java·c语言·c++·学习·算法·c#
小码编匠1 天前
WPF 多线程更新UI的两种实用方案
后端·c#·.net
蜗牛~turbo1 天前
金蝶云星空 调价表取历史价格
java·数据库·sql·c#·database
伽蓝_游戏1 天前
UGUI源码剖析(15):Slider的运行时逻辑与编辑器实现
游戏·ui·unity·性能优化·c#·游戏引擎·.net
太阳的后裔1 天前
随笔一些用C#封装的控件
开发语言·c#
ISDF-工软未来2 天前
C# 泛型简单案例
c#
疯狂的维修2 天前
C#中一段程序类比博图
c#
时光追逐者2 天前
C#/.NET/.NET Core技术前沿周刊 | 第 53 期(2025年9.1-9.7)
c#·.net·.netcore