C#中为何Int16[]会被模式匹配误判为UInt16[]?
C#泛型方法中Int16[]数组在Switch模式匹配中误匹配为UInt16[]的问题分析与解决
问题现象
在C#泛型方法中对Int16[]类型数组执行switch模式匹配时,即便后续存在Int16[]的匹配分支,数组仍会被错误匹配为UInt16[]类型。
示例代码
namespace SwitchError; internal class Program { static void Main(string[] args) { Int16[] arr = new Int16[50]; Console.WriteLine($"Arr is {((arr is UInt16[]) ? " " : "not ")}UInt16[]"); Console.WriteLine($"Arr is {((arr is Int16[]) ? " " : "not ")}Int16[]"); PrintInfo(arr); } static void PrintInfo<T>(T[] array) { string message = array switch { double[] b => "Double", UInt16[] b => "Unsigned Int16", Int16[] b => "Signed Int16", _ => "Unknown type" }; Console.WriteLine("Switch statement says it is an: " + message); } }
输出结果
Arr is not UInt16[] Arr is Int16[] Switch statement says it is an: Unsigned Int16
原因分析
这是C#数组协变性与泛型模式匹配的特殊交互导致的问题:
Int16和UInt16都是16位值类型,底层存储大小一致;- 在泛型方法中,
array的编译时类型是T[],运行时类型是Int16[],但模式匹配在处理值类型数组的类型检查时,错误地将Int16[]判定为与UInt16[]匹配——实际上这两个数组类型完全不同,只是泛型上下文的类型检查逻辑出现了误判。
解决方案
方案1:调整匹配分支顺序
将Int16[]的分支放在UInt16[]之前,让正确的类型先被匹配到:
static void PrintInfo<T>(T[] array) { string message = array switch { double[] b => "Double", Int16[] b => "Signed Int16", UInt16[] b => "Unsigned Int16", _ => "Unknown type" }; Console.WriteLine("Switch statement says it is an: " + message); }
方案2:使用精确的运行时类型检查
通过GetType()获取数组的实际类型,避免模式匹配的误判:
static void PrintInfo<T>(T[] array) { string message = array.GetType() switch { Type t when t == typeof(double[]) => "Double", Type t when t == typeof(UInt16[]) => "Unsigned Int16", Type t when t == typeof(Int16[]) => "Signed Int16", _ => "Unknown type" }; Console.WriteLine("Switch statement says it is an: " + message); }
内容的提问来源于stack exchange,提问作者Salt92
相关产品推荐
相关产品推荐

