我正在尝试克隆ListView
的所有属性,以便我不必进入并使用一行代码分别复制每个属性但经过多次尝试后,我无法获得它工作。
我现在得到错误:
调用目标抛出了异常。
我对属性设置错误的理解是什么?
private ListView generateEmptyClone(ListView toClone)
{
ListView newCopy = new ListView();
foreach (var propToClone in toClone.GetType().GetProperties())
{
PropertyInfo propInfo = newCopy.GetType().GetProperty(propToClone.Name);
if (propInfo.CanWrite)
propInfo.SetValue(newCopy, propToClone.GetValue(toClone, null));
}
return newCopy;
}
答案 0 :(得分:0)
正如RenéVogt在评论中提到的,使用的是访问私有财产。使用BindingFlags将属性限制为您真正需要的属性。
答案 1 :(得分:0)
PropertyInfo.CanWrite
属性仅告诉您属性是否具有setter。它不会告诉您属性是否为public
。
您应该只枚举public
实例属性,如下所示:
foreach (var propToClone in toClone.GetType().
GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
PropertyInfo propInfo = newCopy.GetType().GetProperty(propToClone.Name);
if (propInfo.CanWrite)
propInfo.SetValue(newCopy, propToClone.GetValue(toClone, null));
}
所有static
个实例的ListView
属性已经相同,因此您无需枚举它们。
虽然 可以通过反射设置private
字段(使用GetFields()
)但我认为这不是必要的,因为你可能只有想克隆"正常" ListView
属性。
如果你仍然得到TargetInvocationException
,可能会有另一个问题。 TargetInvocationException
通常会有InnerException
,告诉您究竟出了什么问题。例如,如果您在克隆SelectedIndex
之前克隆Items
属性,则可能会导致IndexOutOfRangeException
。但克隆hte Items
本身可能容易出错。