功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案
原程序:
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,};}
}
处理后程序:
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_NEWERreturn 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,};
#elsePrimitiveType 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_NEWERreturn 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,};
#elsePrimitiveType 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}
}
关键实现说明
-
条件编译符号
-
使用
#if CSHARP_8_OR_NEWER
和#else
隔离不同版本的语法。 -
需在项目文件中定义符号(见下方配置步骤)。
-
-
版本差异处理
-
C# 8.0+:使用简洁的递归模式匹配(
switch
表达式)。 -
C# 7.3:回退到传统的
switch-case
语句。
-
-
功能一致性
两种写法的逻辑完全一致,仅语法形式不同。
项目配置步骤
-
定义编译符号
在.csproj
文件中根据语言版本自动设置符号:
<PropertyGroup><!-- 当使用 C# 8.0+ 时自动定义符号 --><DefineConstants Condition="'$(LangVersion)' >= '8.0'">CSHARP_8_OR_NEWER</DefineConstants>
</PropertyGroup>
手动指定版本(可选)
若需强制兼容性,可手动设置语言版本:
<PropertyGroup><LangVersion>7.3</LangVersion> <!-- 或 8.0、latest 等 -->
</PropertyGroup>
优点
-
无缝适配:根据项目语言版本自动选择最优语法。
-
维护友好:升级到 C# 8.0+ 时无需修改代码,直接享受新语法。
-
编译安全:避免因版本不兼容导致的编译错误。