0

我有两个相同类的对象,我想用脏列表中的字段更新 p2。到目前为止,我设法编写了以下代码,但努力获取 p1 属性的值。我应该在这里将什么对象作为参数传递给GetValue方法。

Person p1 = new Person();
p1.FirstName = "Test";
Person p2 = new Person();

var allDirtyFields = p1.GetAllDirtyFields();
foreach (var dirtyField in allDirtyFields)
{
  p2.GetType()
    .GetProperty(dirtyField)
    .SetValue(p1.GetType().GetProperty(dirtyField).GetValue());
}     

_context.UpdateObject(p2);
_context.SaveChanges();

提前致谢。

4

5 回答 5

2

你应该试试:

foreach (var dirtyField in allDirtyFields)
{
    var prop = p2.GetType().GetProperty(dirtyField);
    prop.SetValue(p2, prop.GetValue(p1));
}

最好将PropertyInfo实例存储在变量中,然后尝试解析两次。

于 2013-08-16T09:38:39.560 回答
1

在每次迭代中,您必须获得对PropertyInfo. 当你调用它的SetValue方法时,你应该传入 2 个参数,你将为其设置属性的对象和你正在设置的实际值。对于后一种,您应该GetValue在同一属性上调用方法,将p1对象作为参数传入,即值的来源。

尝试这个:

foreach (var dirtyField in allDirtyFields)
{
    var p = p2.GetType().GetProperty(dirtyField);
    p.SetValue(p2, p.GetValue(p1));
}

我建议您将dirtyField变量保存在字典中并PropertyInfo从该字典中检索关联的对象。它应该快得多。首先,在你的类中声明一些静态变量:

static Dictionary<string, PropertyInfo> 
    personProps = new Dictionary<string, PropertyInfo>();

然后你可以改变你的方法:

foreach (var dirtyField in allDirtyFields)
{
    PropertyInfo p = null;
    if (!personProps.ContainsKey(dirtyField))
    {
        p = p2.GetType().GetProperty(dirtyField);
        personProps.Add(dirtyField, p);
    }
    else
    {
        p = personProps[dirtyField];
    }
    p.SetValue(p2, p.GetValue(p1));
}
于 2013-08-16T09:38:58.677 回答
1

您知道您不需要检索每个对象的属性吗?

类型元数据对整个类型的任何对象都是通用的。

例如:

// Firstly, get dirty property informations!
IEnumerable<PropertyInfo> dirtyProperties = p2.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
              .Where
              (
                   property => allDirtyFields.Any
                   (
                       field => property.Name == field
                   )
              );

// Then, just iterate the whole property informations, but give the
// "obj" GetValue/SetValue first argument the references "p2" or "p1" as follows:
foreach(PropertyInfo dirtyProperty in dirtyProperties)
{          
       dirtyProperty.SetValue(p2, dirtyProperty.GetValue(p1)); 
}

检查PropertyInfo.GetValue(...)and的第一个参数PropertyInfo.SetValue(...)是否是您要获取或设置整个属性值的对象。

于 2013-08-16T09:50:51.893 回答
0

您需要传递要从中获取属性 value 的实例,如下所示:

p1.GetType().GetProperty(dirtyField).GetValue(p1, null)

如果属性类型被索引,则第二个参数可用于检索某个索引处的值。

于 2013-08-16T09:37:01.387 回答
0

IIrc 您发送 p1 作为保存该值的实例和 null 表示您没有搜索特定的索引值。

于 2013-08-16T09:37:32.093 回答