如何动态迭代两个对象的属性
本文关键字:两个 对象 属性 迭代 何动态 动态 | 更新日期: 2023-09-27 18:27:51
我有两个相同类的对象,我想用Dirty列表中的字段更新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();
提前谢谢。
您应该尝试一下:
foreach (var dirtyField in allDirtyFields)
{
var prop = p2.GetType().GetProperty(dirtyField);
prop.SetValue(p2, prop.GetValue(p1));
}
最好将PropertyInfo
实例存储在一个变量中,然后尝试解析两次。
您知道不需要检索每个对象的属性吗?
类型元数据对于整个类型的任何对象都是通用的。
例如:
// 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(...)
的第一个参数是否是要获取或设置整个属性值的对象。
在每次迭代中,都必须获得对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));
}
您需要传递要从中获取属性值的实例,如下所示:
p1.GetType().GetProperty(dirtyField).GetValue(p1, null)
第二个参数,如果属性类型被索引,则可用于检索某个索引处的值。
IIrc您发送的p1是保存该值的实例,而null表示您没有搜索特定的索引值。