2013-08-16 32 views
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(); 

在此先感谢。

回答

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(...)PropertyInfo.SetValue(...)的第一个参数是要获取或设置全属性的值的对象。

0

IIrc您发送的p1是保存值的实例,null表示您没有搜索特定的索引值。

2

你应该试试:

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

这是一个更好的存储PropertyInfo例如在变量,然后设法解决它的两倍。

+0

谢谢,请你举个例子,我可以如何为每个变量存储PropertyInfo – Scorpion

+1

其实,它已经在我的代码中了,不是吗? ''prop'局部变量而不是'p2.GetType().setValue()'和'p1.GetType()。GetValue()'保存一个'GetType()'调用,这是非常昂贵的。 – MarcinJuraszek

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)); 
}