提问人:user2653422 提问时间:6/6/2023 更新时间:6/6/2023 访问量:93
通过反射设置属性值不起作用,而直接在 C 中设置属性值#
Setting property value via reflection doesn't work while setting it directly works in C#
问:
我正在尝试通过 C# 中的反射来设置框架类型的属性的值。
该物业似乎是双打的容器,用单位丰富了双打。TargetProp
TargetPropType
做以下工作
parentOfProperty.TargetProp = 5.0;
虽然以下操作失败,但出现 System.ArgumentException:“'System.Double' 类型的对象无法转换为'TargetPropType' 类型。
PropertyInfo setProperty = parentOfProperty.GetType().GetProperty("TargetProp");
setProperty.SetValue(parentOfProperty, 5.0, null);
以下操作也会失败,并出现相同的异常
setProperty.GetSetMethod()?.Invoke(parentOfProperty, new object[] { 5.0 });
在反射分配失败时,它的第一个分配会有什么不同?
答:
将属性直接设置为有效,但使用反射则无效,因为属性的类型具有隐式转换,如您在注释中链接的那样。反射不会解析隐式转换运算符。double
int
因此,您只需手动调用隐式转换运算符,并将结果传递给:SetValue
TargetPropType arg = 5.0;
setProperty.SetValue(parentOfProperty, arg, null);
但是,您似乎想要一个更通用的解决方案。从评论:
该程序读取输入文件和转换文件。由转换文件提供,可以是框架中的任何属性。在运行时,程序只知道某些值必须转换为 。
TargetProp
TargetProp
我建议使用 a 来准确记录如何创建您可能遇到的每种类型的属性。我们称之为 .例如,将有一个条目,其中键为 ,值如下所示:Dictionary<Type, Func<object, object>>
conversionsDict
conversionsDict
typeof(TargetPropType)
o => {
TargetPropType result = (double)o; // assuming only doubles can get converted to TargetPropType
return result;
// or simply "return new TargetPropType((double)o)" if that's what the implicit conversion does
}
您可以将所有需要转换的类型放入 中,然后执行以下操作:conversionsDict
PropertyInfo setProperty = parentOfProperty.GetType().GetProperty(someStringYouGetFromTransformationFile);
Type propertyType = setProperty.PropertyType;
object value = theValueYouWantToSet;
if (conversionsDict.TryGetValue(propertyType, out var converter)) {
value = converter(value);
}
setProperty.SetValue(parentOfProperty, value, null);
或者,您可以使用反射来调用隐式转换运算符。该运算符编译为 IL 中名为 的方法,尽管我不确定是否在任何地方指定了这种方法。op_Implicit
// list out the primitive types that needs no conversion
var listOfPrimitives = new List<Type>() { ... };
object value = theValueYouWantToSet;
if (!listOfPrimitives.Contains(propertyType)) {
var method = propertyType.GetMethod("op_Implicit", new[] { value.GetType() });
if (method != null) {
value = method.Invoke(null, new[] { value });
}
}
setProperty.SetValue(parentOfProperty, value, null);
另请参阅这篇使用 API 的帖子。TypeDescriptor
评论
TargetProp
TargetProp
TargetProp
Dictionary<Type, Func<object, object>>
TaregtProp