C# 什么样的C/Linq代码在不知道对象类型的情况下复制两个对象之间所有匹配的属性名称值?
我有一个众所周知的POCO类Customer要从我的方法返回。但是,我只填充由不断变化的表达式p=>new{p.id,p.name}指定的属性,例如,作为方法的参数 不知何故,我需要复制这两个对象之间的所有匹配字段C# 什么样的C/Linq代码在不知道对象类型的情况下复制两个对象之间所有匹配的属性名称值?,c#,reflection,C#,Reflection,我有一个众所周知的POCO类Customer要从我的方法返回。但是,我只填充由不断变化的表达式p=>new{p.id,p.name}指定的属性,例如,作为方法的参数 不知何故,我需要复制这两个对象之间的所有匹配字段 var returnObject = IList<Customer>(); var partialFieldObject = DC.Customers.Select( expParameter); // wont know the fields foreach( var
var returnObject = IList<Customer>();
var partialFieldObject = DC.Customers.Select( expParameter); // wont know the fields
foreach( var partialRecord in partialFieldObject)
{ foreach (var property in partialRecord // Pseudo code)
{
returnObject[property] = property.value; // More Pseudo code
}
}
End result is a strongly typed Customer POCO returned that only has the selected fields populated with values.
你可以使用-它是用来做这件事的,我认为一些简单的反射就可以做到这一点,假设partialFieldObject上的属性与Customer上的属性完全区分大小写 如果接受了,我在接受基类型并需要镜像内容的构造函数中使用了以下内容:
var thisType = this.GetType();
foreach (var prop in baseObj.GetType().GetProperties()
.Where(p => thisType.GetProperty(p.Name) != null))
{
var propGetter = prop.GetGetMethod();
var propSetter = thisType.GetProperty(prop.Name).GetSetMethod();
if (propSetter != null)
propSetter.Invoke(this, new[] { propGetter.Invoke(baseObj, null) });
}
基本上,逐步检查baseObj类型中的每个属性,其中该类型具有具有匹配名称的属性,并找到baseObj类型上的get方法以及该类型上匹配的命名属性的set方法,如果该类型上有set方法可用,使用在baseObj类型上调用get方法返回的方法调用它
适用于两种类型上任何匹配类型的公共和私有属性
注意:对于循环中的.Where func,您需要一个对System.Linq的引用没有什么不同,只是我找到的最紧凑、最干净的表单:
void CopyProperties(object src, object dest) {
foreach (var source in src.GetType().GetProperties().Where(p => p.CanRead)) {
var prop = dest.GetType().GetProperty(source.Name);
if (prop?.CanWrite == true)
prop.SetValue(dest, source.GetValue(src, null), null);
}
}
通过匹配,我的意思是复制相同名称的所有属性的值。问题是AutoMapper无法确定类型时无法映射。它会看到没有任何属性的对象。@Dr.Zim查看API,您可以使用CreateMap函数的通用形式,也可以使用基于参数的函数,通过它可以传递类型。所以你可以做AutoMapper.Mapper.CreateMapsource.GetType,destination.getTypeFantactive!我不得不添加一些空值检查,但之后,它就像一个符咒。谢谢!此反射工程存在性能泄漏。最好使用Linq表达式赋值,并为整个应用程序编译它。您能详细说明您的答案吗?只发布代码通常没有多大帮助。这一行应该是:prop.SetValuedest,source.GetValuesrc,null,null;
public static void CopyPropertiesTo<T, TU>(this T source, TU dest)
{
var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList();
var destProps = typeof(TU).GetProperties()
.Where(x => x.CanWrite)
.ToList();
foreach (var sourceProp in sourceProps)
{
if (destProps.Any(x => x.Name == sourceProp.Name))
{
var p = destProps.First(x => x.Name == sourceProp.Name);
p.SetValue(dest, sourceProp.GetValue(source, null), null);
}
}
}
void CopyProperties(object src, object dest) {
foreach (var source in src.GetType().GetProperties().Where(p => p.CanRead)) {
var prop = dest.GetType().GetProperty(source.Name);
if (prop?.CanWrite == true)
prop.SetValue(dest, source.GetValue(src, null), null);
}
}
void Copy(object copyToObject, object copyFromObject)
{
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
FieldInfo[] fields = copyFromObject.GetType().GetFields(flags);
for (int i = 0; i < fields.Length; ++i)
{
FieldInfo fromField = copyFromObject.GetType().GetField(fields[i].Name, flags);
FieldInfo toField = copyToObject.GetType().GetField(fields[i].Name, flags);
if(fromField != null)
{
toField.SetValue(copyToObject, fromField.GetValue(copyFromObject));
}
}
}