C# 反射 - 对象与目标类型不匹配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19101222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:05:30  来源:igfitidea点击:

C# Reflection - Object does not match target type

c#reflection

提问by Dustin Kofoed

I'm trying to use the propertyInfo.SetValue()method to set an object property value with reflection, and I'm getting the exception "Object does not match target type". It doesn't really make sense (at least to me!) as I'm just trying to set a simple string property on an object with a string replacement value. Here's a code snippet - this is contained within a recursive function so there's a bunch more code, but this is the guts:

我正在尝试使用该propertyInfo.SetValue()方法通过反射设置对象属性值,但出现异常“对象与目标类型不匹配”。这真的没有意义(至少对我来说!)因为我只是想在具有字符串替换值的对象上设置一个简单的字符串属性。这是一个代码片段——它包含在一个递归函数中,所以还有更多的代码,但这是胆量:

PropertyInfo fieldPropertyInfo = businessObject.GetType().GetProperties().FirstOrDefault(f => f.Name.ToLower() == piecesLeft[0].ToLower());
businessObject = fieldPropertyInfo.GetValue(businessObject, null);

fieldPropertyInfo.SetValue(businessObject, replacementValue, null);

I've verified that businessObject" andreplacementValue` are both the same type by doing this comparison, which returned true:

我已经businessObject" and通过做这个比较验证了replacementValue` 是相同的类型,它返回 true:

businessObject.GetType() == replacementValue.GetType()

采纳答案by Jeroen van Langen

You're trying to set the value of the propertyinfo value's. Because you're overwriting the businessObject

您正在尝试设置 propertyinfo 值的值。因为你正在覆盖businessObject

PropertyInfo fieldPropertyInfo = businessObject.GetType().GetProperties()
                                 .FirstOrDefault(f => f.Name.ToLower() == piecesLeft[0].ToLower());

// The result should be stored into another variable here:
businessObject = fieldPropertyInfo.GetValue(businessObject, null);

fieldPropertyInfo.SetValue(businessObject, replacementValue, null);

It should be something like:

它应该是这样的:

PropertyInfo fieldPropertyInfo = businessObject.GetType().GetProperties()
                                 .FirstOrDefault(f => f.Name.ToLower() == piecesLeft[0].ToLower());

// also you should check if the propertyInfo is assigned, because the 
// given property looks like a variable.
if(fieldPropertyInfo == null)
    throw new Exception(string.Format("Property {0} not found", f.Name.ToLower()));

// you are overwriting the original businessObject
var businessObjectPropValue = fieldPropertyInfo.GetValue(businessObject, null);

fieldPropertyInfo.SetValue(businessObject, replacementValue, null);

回答by Reed Copsey

You're trying to set the value of the property on businessObjectto another value of the type of businessObject, not the type of that property.

您正在尝试将businessObject上的属性值设置为 类型的另一个值businessObject,而不是该属性的类型。

For this code to work, replacementValueneeds to be the same type as the field defined by piecesLeft[0], and it obviously is not that type.

要使此代码工作,replacementValue需要与 定义的字段类型相同piecesLeft[0],显然不是那种类型。

回答by Jon Skeet

I suspect you just want to remove the second line. What's it doing there anyway? You're fetching the value of the property fromthe object referred to by businessObject- and setting that to the new value of businessObject. So if this really is a string property, the value of businessObjectwill be a string reference afterwards - and you're then trying to use that as the target for settingthe property! It's a bit like doing this:

我怀疑你只是想删除第二行。它到底在那里做什么?您正在引用的对象中获取属性的值businessObject- 并将其设置为 的新值businessObject。因此,如果这确实是一个字符串属性,则之后的值businessObject将是一个字符串引用 - 然后您尝试将其用作设置属性的目标!这有点像这样做:

dynamic businessObject = ...;
businessObject = businessObject.SomeProperty; // This returns a string, remember!
businessObject.SomeProperty = replacementValue;

That's not going to work.

那是行不通的。

It's not clear what replacementValueis - whether it's the replacement string or a business object to fetch the real replacement value from, but I suspect you either want:

目前尚不清楚是什么replacementValue- 无论是替换字符串还是从中获取真正替换值的业务对象,但我怀疑您要么想要:

PropertyInfo fieldPropertyInfo = businessObject.GetType().GetProperties()
      .FirstOrDefault(f => f.Name.ToLower() == piecesLeft[0].ToLower());
fieldPropertyInfo.SetValue(businessObject, replacementValue, null);

Or:

或者:

PropertyInfo fieldPropertyInfo = businessObject.GetType().GetProperties()
      .FirstOrDefault(f => f.Name.ToLower() == piecesLeft[0].ToLower());
object newValue = fieldPropertyInfo.GetValue(replacementValue, null);
fieldPropertyInfo.SetValue(businessObject, newValue, null);