如何通过反射将可空枚举(enum?)成功赋值给可空int(int?)属性?
解决反射赋值可空枚举到可空int属性的问题
这个问题我之前也踩过坑,核心原因是反射的SetValue方法不会自动处理可空类型之间的隐式枚举转整数转换。直接赋值时C#编译器会帮你做隐式转换,但反射是纯运行时操作,不会自动识别这种类型兼容逻辑,直接传enum?对象会因类型不匹配导致失败。
下面给你两种可行的解决思路:
方案一:手动拆包枚举值并转换为可空int
先判断源可空枚举是否有值,若不为空就取出枚举的整数值,再包装成int?类型后赋值:
static void Main(string[] args) { Dc dc = new Dc { Solution = Solution.Upgrade }; Model model = new Model { }; var psolution = model.GetType().GetProperty("Solution"); // 手动处理可空枚举到可空int的转换 int? targetValue = dc.Solution.HasValue ? (int?)dc.Solution.Value : null; psolution.SetValue(model, targetValue); // 现在可以成功赋值 } // 假设你的枚举和类定义如下 enum Solution { Upgrade = 1, Downgrade = 2 } class Dc { public Solution? Solution { get; set; } } class Model { public int? Solution { get; set; } }
方案二:结合Convert.ChangeType处理可空类型
Convert.ChangeType默认不支持直接转换可空类型,需要先获取可空类型的底层类型(比如int?的底层是int),转换枚举值后再装箱为可空类型:
static void Main(string[] args) { Dc dc = new Dc { Solution = Solution.Upgrade }; Model model = new Model { }; var psolution = model.GetType().GetProperty("Solution"); object valueToSet = null; if (dc.Solution.HasValue) { // 获取目标可空类型的底层值类型 var underlyingType = Nullable.GetUnderlyingType(psolution.PropertyType); // 转换枚举值为底层类型,再装箱为可空类型 valueToSet = Convert.ChangeType(dc.Solution.Value, underlyingType); } psolution.SetValue(model, valueToSet); // 同样可以成功赋值 }
至于为什么直接赋值model.Solution = (int?)dc.Solution能成功?因为C#编译器在编译阶段就把这个操作转换成了「拆包枚举值→转成int→包装成int?」的逻辑,但反射是动态运行时调用,没有这个编译阶段的转换加持,所以需要我们手动处理类型适配。
内容的提问来源于stack exchange,提问作者1pgjy
相关产品推荐
相关产品推荐

