如何在泛型方法中调用对应类型的非泛型重载方法
问题原因
C# 的重载决议在编译阶段完成,对于泛型方法来说,编译期只能根据T的约束条件匹配目标方法。你当前给T加的约束是struct(值类型),但BitConverter.GetBytes没有适配任意值类型的重载,所以无法通过编译。
可行实现方案
方案1:类型模式匹配(推荐)
性能最优,编译期即可覆盖所有合法类型,不会有运行时意外报错,适合目标方法重载数量有限的场景,示例代码如下:
static byte[] GetBytes<T>(T value) where T : struct { return value switch { int intVal => BitConverter.GetBytes(intVal), long longVal => BitConverter.GetBytes(longVal), short shortVal => BitConverter.GetBytes(shortVal), uint uintVal => BitConverter.GetBytes(uintVal), ulong ulongVal => BitConverter.GetBytes(ulongVal), ushort ushortVal => BitConverter.GetBytes(ushortVal), float floatVal => BitConverter.GetBytes(floatVal), double doubleVal => BitConverter.GetBytes(doubleVal), char charVal => BitConverter.GetBytes(charVal), bool boolVal => BitConverter.GetBytes(boolVal), _ => throw new NotSupportedException($"类型 {typeof(T).FullName} 未被BitConverter支持") }; }
如果使用低于.NET Core 3.0的版本,不支持switch表达式,可以替换为if-else类型判断加强制转换的写法,逻辑完全一致。
方案2:dynamic动态调度
写法最简洁,不需要手动枚举所有重载,但是会产生运行时的动态解析开销,且编译期不会做类型合法性校验,传入不支持的类型时会在运行时报错,示例代码如下:
static byte[] GetBytes<T>(T value) where T : struct { return BitConverter.GetBytes((dynamic)value); }
这个方案的原理是把参数的类型解析推迟到运行时,由DLR(动态语言运行时)匹配对应的重载。
内容的提问来源于stack exchange,提问作者CrumbleZ
相关产品推荐
相关产品推荐

