为何单元测试中System.Int32是否可分配给INumber<>返回false?
问题原因分析
出现这种结果差异的核心原因通常是控制台应用与单元测试项目的目标.NET版本不一致,具体逻辑差异如下:
INumber<>是.NET 7引入的泛型数值接口,但在.NET 7及更早版本中,typeof(int).IsAssignableTo(typeof(INumber<>))会返回false——此时反射方法对开放式泛型(未指定类型参数的泛型接口)的判断逻辑是:仅当类型直接实现该开放式泛型时才返回true,而int实际实现的是封闭式泛型INumber<int>,并非开放式的INumber<>。- 在.NET 8中,微软调整了反射方法的判断逻辑,
IsAssignableTo会识别出类型实现了该开放式泛型的某个构造版本(比如INumber<int>),因此typeof(int).IsAssignableTo(typeof(INumber<>))会返回true。
如果你的控制台应用目标框架是.NET 8,而单元测试项目仍使用.NET 7及以下版本,就会出现两边执行结果不一致的情况。
除此之外还有两种次要可能性:
- 单元测试项目未正确引用必要程序集:比如遗漏了
System.Numerics相关程序集(不过这种情况通常会导致编译错误,而非运行时返回false)。 - 单元测试项目语言版本设置过低:
INumber<>需要C# 11及以上版本支持,如果单元测试项目的LangVersion设置低于11,可能导致反射时无法正确识别接口实现(同样,编译阶段通常会报错)。
解决方法
- 统一目标框架版本:将单元测试项目的目标框架升级到与控制台应用相同的版本(比如.NET 8)。
- 调整反射判断逻辑:如果无法升级框架,改用更准确的方式检测类型是否实现了
INumber<>的某个构造版本:var isNumber = typeof(int).GetInterfaces() .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(INumber<>));
内容的提问来源于stack exchange,提问作者rory.ap
相关产品推荐
相关产品推荐

