.NET Framework 4.0插件项目使用double.NaN等特殊值触发编译错误
问题场景
基于.NET Framework 4.0开发依赖NotepadPlusPlusPluginPack.NET的C#项目时,只要代码中使用double.NaN、double.NegativeInfinity、double.PositiveInfinity这些特殊常量,就会触发编译错误——哪怕只是简单声明变量赋值都会报错。比如写double inf = double.PositiveInfinity;,会收到类似这样的错误:
<source code filename>.cs(784) : error : syntax error at token 'inf' in: IL_03db: ldc.r8 inf
而单独创建的普通.NET 4.0项目可以正常使用这些常量,替换成普通double值后插件项目也能正常构建,推测问题出在NotepadPlusPlusPluginPack.NET依赖的ILMerge工具上。VS2019和2022都存在这个问题,之前在.NET 6.0项目中使用这些常量则完全正常。
原因分析
NotepadPlusPlusPluginPack.NET在打包插件时会用到ILMerge,适配.NET Framework 4.0的旧版ILMerge对ldc.r8 inf、ldc.r8 nan这类表示特殊浮点数的IL指令处理存在缺陷,会把这些指令误判为语法错误,导致编译失败。普通.NET项目不需要经过ILMerge的特殊处理,所以不会触发这个问题。
可行解决方案
1. 用等效数值表达式替代框架常量
直接用数学表达式生成对应的特殊值,绕开框架常量的引用:
// 替代double.PositiveInfinity double posInf = 1.0 / 0.0; // 替代double.NegativeInfinity double negInf = -1.0 / 0.0; // 替代double.NaN double nanVal = 0.0 / 0.0;
2. 自定义常量类封装特殊值
在项目中创建自己的常量类,统一管理这些特殊值,避免直接引用框架的常量:
public static class DoubleSpecialValues { public const double PositiveInfinity = 1.0 / 0.0; public const double NegativeInfinity = -1.0 / 0.0; public const double NaN = 0.0 / 0.0; }
之后在代码里直接用DoubleSpecialValues.PositiveInfinity即可。
3. 调整ILMerge配置(进阶)
如果能获取NotepadPlusPlusPluginPack.NET的构建配置文件,可以检查ILMerge的参数设置,尝试添加支持特殊浮点数指令的配置项。不过这个方法需要熟悉ILMerge的使用,适合有一定底层工具经验的开发者。
内容的提问来源于stack exchange,提问作者molsonkiko

