如何实现支持Parse、ParseExact方法的值类型通用泛型解析方法
实现方案
原来的代码无法编译的核心原因是C#泛型系统没有原生支持「类型包含指定静态方法」的约束,我们可以根据你使用的.NET版本选择以下两种实现:
方案1:全版本兼容的反射实现
适用于所有.NET Framework、.NET Core版本,运行时动态查找调用Parse/ParseExact方法:
using System.Globalization; using System.Reflection; // 此处保留你自定义的Flags枚举定义 public enum Flags { // 你的枚举值 } public class YourClass { public Dictionary<Flags, object> FlagValues { get; } = new Dictionary<Flags, object>(); public T GetFlagValue<T>(Flags flag, string formatString = null) where T : struct { T result = default; // 取值同时校验原始值是否为字符串类型 if (!FlagValues.TryGetValue(flag, out object flagValueRaw) || flagValueRaw is not string inputStr) { return result; } try { if (string.IsNullOrEmpty(formatString)) { // 查找匹配签名的Parse静态方法 MethodInfo parseMethod = typeof(T).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, new[] { typeof(string), typeof(IFormatProvider) }); if (parseMethod == null) { throw new NotSupportedException($"类型{typeof(T).Name}不支持指定签名的Parse方法"); } result = (T)parseMethod.Invoke(null, new object[] { inputStr, CultureInfo.InvariantCulture }); } else { // 查找匹配签名的ParseExact静态方法 MethodInfo parseExactMethod = typeof(T).GetMethod("ParseExact", BindingFlags.Public | BindingFlags.Static, new[] { typeof(string), typeof(string), typeof(IFormatProvider) }); if (parseExactMethod == null) { throw new NotSupportedException($"类型{typeof(T).Name}不支持指定签名的ParseExact方法"); } result = (T)parseExactMethod.Invoke(null, new object[] { inputStr, formatString, CultureInfo.InvariantCulture }); } } catch (TargetInvocationException invocationException) { // 抛出解析阶段的原始异常 throw invocationException.InnerException ?? invocationException; } return result; } }
如果需要避免解析失败抛出异常,可以自行修改逻辑调用对应类型的TryParse/TryParseExact方法,兼容失败场景。
方案2:.NET 7+ 编译期校验的高性能实现
.NET 7开始引入了泛型数学相关的静态接口,所有内置值类型(int、double、TimeSpan、DateTime等)都实现了IParsable<TSelf>和IExactParsable<TSelf>接口,可直接用泛型约束实现编译期校验,无反射性能损耗:
using System.Globalization; public class YourClass { public Dictionary<Flags, object> FlagValues { get; } = new Dictionary<Flags, object>(); public T GetFlagValue<T>(Flags flag, string formatString = null) where T : struct, IParsable<T>, IExactParsable<T> { T result = default; if (!FlagValues.TryGetValue(flag, out object flagValueRaw) || flagValueRaw is not string inputStr) { return result; } if (string.IsNullOrEmpty(formatString)) { result = T.Parse(inputStr, CultureInfo.InvariantCulture); } else { result = T.ParseExact(inputStr, formatString, CultureInfo.InvariantCulture); } return result; } }
该版本逻辑和你给出的示意代码完全一致,编译期就会检查传入的T是否符合要求,不会出现运行时找不到方法的问题。
内容的提问来源于stack exchange,提问作者gryz
相关产品推荐
相关产品推荐

