我有2個相同對象的實例o1和o2。如果我正在做的事情如遍歷一個對象並找到非空屬性
if (o1.property1 != null) o1.property1 = o2.property1
爲對象的所有屬性。循環遍歷對象中的所有屬性並做到這一點最有效的方法是什麼?我看到有人使用PropertyInfo來檢查屬性的nulll,但似乎他們只能通過PropertyInfo集合,但沒有鏈接屬性的操作。
謝謝。
我有2個相同對象的實例o1和o2。如果我正在做的事情如遍歷一個對象並找到非空屬性
if (o1.property1 != null) o1.property1 = o2.property1
爲對象的所有屬性。循環遍歷對象中的所有屬性並做到這一點最有效的方法是什麼?我看到有人使用PropertyInfo來檢查屬性的nulll,但似乎他們只能通過PropertyInfo集合,但沒有鏈接屬性的操作。
謝謝。
可以與反思這樣做:
public void CopyNonNullProperties(object source, object target)
{
// You could potentially relax this, e.g. making sure that the
// target was a subtype of the source.
if (source.GetType() != target.GetType())
{
throw new ArgumentException("Objects must be of the same type");
}
foreach (var prop in source.GetType()
.GetProperties(BindingFlags.Instance |
BindingFlags.Public)
.Where(p => !p.GetIndexParameters().Any())
.Where(p => p.CanRead && p.CanWrite))
{
var value = prop.GetValue(source, null);
if (value != null)
{
prop.SetValue(target, value, null);
}
}
}
從你的例子來看,我認爲你在尋找這樣的事情:
static void CopyTo<T>(T from, T to)
{
foreach (PropertyInfo property in typeof(T).GetProperties())
{
if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0))
continue;
object value = property.GetValue(to, null);
if (value != null)
property.SetValue(to, property.GetValue(from, null), null);
}
}
如果你要使用很多次,你可以使用編譯表達式爲更好的性能:
public static class Mapper<T>
{
static Mapper()
{
var from = Expression.Parameter(typeof(T), "from");
var to = Expression.Parameter(typeof(T), "to");
var setExpressions = typeof(T)
.GetProperties()
.Where(property => property.CanRead && property.CanWrite && !property.GetIndexParameters().Any())
.Select(property =>
{
var getExpression = Expression.Call(from, property.GetGetMethod());
var setExpression = Expression.Call(to, property.GetSetMethod(), getExpression);
var equalExpression = Expression.Equal(Expression.Convert(getExpression, typeof(object)), Expression.Constant(null));
return Expression.IfThen(Expression.Not(equalExpression), setExpression);
});
Map = Expression.Lambda<Action<T, T>>(Expression.Block(setExpressions), from, to).Compile();
}
public static Action<T, T> Map { get; private set; }
}
而且使用它像這樣:
Mapper<Entity>.Map(e1, e2);
謝謝,喬恩,完美無缺! – NewDTinStackoverflow