使用反射设置属性值抛出异常(MAUI+Community MVVM场景)
问题分析与解决
核心错误原因
SetValue参数顺序颠倒:PropertyInfo.SetValue的第一个参数是要修改的目标对象实例,第二个参数是要设置的属性值。你当前代码把t.Value(属性值)当成了目标实例传进去,导致类型不匹配,直接抛出"Object does not match target type."异常。- 结构体值类型的装箱问题:结构体是值类型,直接通过反射修改时会触发装箱操作,修改的是装箱后的副本,不会影响原
Content.Structure的实际值——就算参数顺序改对了,原结构体也不会被更新。
修正后的代码
messenger.Register<ObjectMessage>(this, (o, t) => { switch (t.Sender) { case "Changes": try { var structureType = Content.Structure.GetType(); var prop = structureType.GetProperty((string)t.Message); if (prop == null) break; // 1. 结构体是值类型,先创建原实例的副本 var structInstance = Content.Structure; // 2. 转换值到属性对应的类型 var convertedValue = Convert.ChangeType(t.Value, prop.PropertyType); // 3. 给副本的属性赋值 prop.SetValue(structInstance, convertedValue); // 4. 将修改后的副本重新赋值回Content.Structure Content.Structure = (dynamic)structInstance; } catch(Exception ex) { #if DEBUG Console.WriteLine($"Exception - ex.Message = {ex.Message}"); #endif } HasChanges = Content.Structure != DupeContent.Structure; break; } });
关键说明
- 参数顺序修正:把
prop.SetValue(t.Value, ...)改成prop.SetValue(structInstance, convertedValue),确保目标实例是结构体对象,值是转换后的正确类型。 - 值类型处理:通过先拷贝原结构体实例、修改副本再赋值回去的方式,避免装箱副本无法同步到原对象的问题。用
dynamic可以简化类型转换,也可以用structureType做显式强制转换。
内容的提问来源于stack exchange,提问作者Nodoid
相关产品推荐
相关产品推荐

