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

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

相关推荐
shandianchengzi2 小时前
【记录】Unity|Unity从安装到打开一个Github项目(以我的世界(仿)为例)
unity·c#·游戏引擎·github·我的世界·mc
咕白m6253 小时前
通过 C# 给Word文档添加水印:文字水印、图片水印
后端·c#
YuanlongWang5 小时前
C# 基础——async/await 的实现原理与最佳实践
开发语言·c#
kalvin_y_liu5 小时前
ManySpeech —— 使用 C# 开发人工智能语音应用
开发语言·人工智能·c#·语音识别
唐青枫6 小时前
C#.NET FluentSqlKata 全面解析:基于链式语法的动态 SQL 构建
c#·.net
加号316 小时前
【C#】获取电脑网卡MAC地址
windows·c#
yi碗汤园16 小时前
【超详细】C#自定义工具类-StringHelper
开发语言·前端·unity·c#·游戏引擎
sali-tec16 小时前
C# 基于halcon的视觉工作流-章49-网面破损
开发语言·图像处理·算法·计算机视觉·c#
YuanlongWang16 小时前
c# ABP vNext 框架详解及其模块化开发思想介绍
开发语言·c#
张人玉16 小时前
WPF布局控件(界面骨架核心)
开发语言·c#·wpf·布局控件