C#反射-将两个对象合并在一起
如果对象a的属性为null,我需要将其更新为对象B的等效属性(如果该属性不为null)。我想要可以用于各种对象的代码 我有一个版本一直在工作,直到其中一个对象包含一个类型为List的propert,这就是我在下面的代码中有一个空白的地方。我的主要问题是如何最好地实现这部分代码。第二,有没有更好的方法来完成这整个事情,第三,我知道它永远不会很快,但任何建议,以加快它将不胜感激 提前谢谢C#反射-将两个对象合并在一起,c#,C#,如果对象a的属性为null,我需要将其更新为对象B的等效属性(如果该属性不为null)。我想要可以用于各种对象的代码 我有一个版本一直在工作,直到其中一个对象包含一个类型为List的propert,这就是我在下面的代码中有一个空白的地方。我的主要问题是如何最好地实现这部分代码。第二,有没有更好的方法来完成这整个事情,第三,我知道它永远不会很快,但任何建议,以加快它将不胜感激 提前谢谢 public T MergeWith<T, U>(T primarySource, U second
public T MergeWith<T, U>(T primarySource, U secondarySource) where U : class, T
{
Type primaryType = typeof(T);
Type secondaryType = typeof(U);
foreach (PropertyInfo primaryInfo in primaryType.GetProperties())
{
if (primaryInfo.CanWrite)
{
object currentPrimary = primaryInfo.GetValue(primarySource, null);
PropertyInfo secondaryInfo = secondaryType.GetProperty(primaryInfo.Name);
object currentSecondary = secondaryInfo.GetValue(secondarySource, null);
if (currentPrimary == null && currentSecondary != null)
{
primaryInfo.SetValue(primarySource, currentSecondary, null);
}
else if ((currentPrimary != null && currentSecondary != null) && isChildClass(primaryInfo))
{
if (isCollection(currentPrimary))
{
// here
}
else
{
MethodInfo method = typeof(NavigationModel).GetMethod("MergeWith");
MethodInfo generic = method.MakeGenericMethod(primaryInfo.PropertyType, primaryInfo.PropertyType);
object returnChild = generic.Invoke(this, new object[2] { currentPrimary, currentSecondary });
}
}
}
}
return primarySource;
}
private bool isCollection(object property)
{
return typeof(ICollection).IsAssignableFrom(property.GetType())
|| typeof(ICollection<>).IsAssignableFrom(property.GetType());
}
private bool isChildClass(PropertyInfo propertyInfo)
{
return (propertyInfo.PropertyType.IsClass && !propertyInfo.PropertyType.IsValueType &&
!propertyInfo.PropertyType.IsPrimitive && propertyInfo.PropertyType.FullName != "System.String");
}
public T MergeWith(T primarySource,U secondarySource),其中U:class,T
{
类型primaryType=类型(T);
类型secondaryType=类型(U);
foreach(primaryType.GetProperties()中的PropertyInfo primaryInfo)
{
if(primaryInfo.CanWrite)
{
对象currentPrimary=primaryInfo.GetValue(primarySource,null);
PropertyInfo secondaryInfo=secondaryType.GetProperty(primaryInfo.Name);
object currentSecondary=secondaryInfo.GetValue(secondarySource,null);
如果(currentPrimary==null&¤tSecondary!=null)
{
primaryInfo.SetValue(primarySource,currentSecondary,null);
}
else if((currentPrimary!=null&¤tSecondary!=null)&&isChildClass(primaryInfo))
{
if(isCollection(currentPrimary))
{
//这里
}
其他的
{
MethodInfo method=typeof(NavigationModel).GetMethod(“合并”);
MethodInfo generic=method.MakeGenericMethod(primaryInfo.PropertyType,primaryInfo.PropertyType);
object returnChild=generic.Invoke(这个,新对象[2]{currentPrimary,currentSecondary});
}
}
}
}
返回主源;
}
私有布尔isCollection(对象属性)
{
返回typeof(ICollection).IsAssignableFrom(property.GetType())
||typeof(ICollection).IsAssignableFrom(property.GetType());
}
私有bool是ChildClass(PropertyInfo PropertyInfo)
{
返回(propertyInfo.PropertyType.IsClass&!propertyInfo.PropertyType.IsValueType&&
!propertyInfo.PropertyType.IsPrimitive&&propertyInfo.PropertyType.FullName!=“System.String”);
}
我已经创建了下面的扩展方法,用于我的最新项目,它可以很好地工作,无论是集合还是其他。它是您在方法中所做工作的一个非常简单的版本。我的两个类必须是同一类型。您在收集时遇到了什么问题
public static class ExtensionMethods
{
public static TEntity CopyTo<TEntity>(this TEntity OriginalEntity, TEntity NewEntity)
{
PropertyInfo[] oProperties = OriginalEntity.GetType().GetProperties();
foreach (PropertyInfo CurrentProperty in oProperties.Where(p => p.CanWrite))
{
if (CurrentProperty.GetValue(NewEntity, null) != null)
{
CurrentProperty.SetValue(OriginalEntity, CurrentProperty.GetValue(NewEntity, null), null);
}
}
return OriginalEntity;
}
}
公共静态类扩展方法
{
公共静态tenty CopyTo(此tenty OriginalEntity,tenty NewEntity)
{
PropertyInfo[]oProperties=OriginalEntity.GetType().GetProperties();
foreach(PropertyInfo-CurrentProperty in-oProperties.Where(p=>p.CanWrite))
{
if(CurrentProperty.GetValue(NewEntity,null)!=null)
{
CurrentProperty.SetValue(OriginalEntity,CurrentProperty.GetValue(NewEntity,null),null);
}
}
回归本源性;
}
}
Hi I修改了Ben Robinson解决方案,以避免覆盖集合或列表,相反,它将一个对象的元素添加到发生合并的另一个对象中:
public static class ExtensionMethods
{
public static TEntity CopyTo<TEntity>(this TEntity OriginalEntity, TEntity EntityToMergeOn)
{
PropertyInfo[] oProperties = OriginalEntity.GetType().GetProperties();
foreach (PropertyInfo CurrentProperty in oProperties.Where(p => p.CanWrite))
{
var originalValue = CurrentProperty.GetValue(EntityToMergeOn);
if (originalValue != null)
{
IListLogic<TEntity>(OriginalEntity, CurrentProperty, originalValue);
}
else
{
var value = CurrentProperty.GetValue(OriginalEntity, null);
CurrentProperty.SetValue(EntityToMergeOn, value, null);
}
}
return OriginalEntity;
}
private static void IListLogic<TEntity>(TEntity OriginalEntity, PropertyInfo CurrentProperty, object originalValue)
{
if (originalValue is IList)
{
var tempList = (originalValue as IList);
var existingList = CurrentProperty.GetValue(OriginalEntity) as IList;
foreach (var item in tempList)
{
existingList.Add(item);
}
}
}
}
公共静态类扩展方法
{
公共静态tenty CopyTo(此tenty OriginalEntity,tenty EntityToMergeOn)
{
PropertyInfo[]oProperties=OriginalEntity.GetType().GetProperties();
foreach(PropertyInfo-CurrentProperty in-oProperties.Where(p=>p.CanWrite))
{
var originalValue=CurrentProperty.GetValue(EntityToMergeOn);
if(originalValue!=null)
{
IListLogic(原始属性、当前属性、原始值);
}
其他的
{
var value=CurrentProperty.GetValue(原始属性,null);
CurrentProperty.SetValue(EntityToMergeOn,value,null);
}
}
回归本源性;
}
私有静态无效IListLogic(TEntity OriginalEntity、PropertyInfo CurrentProperty、object originalValue)
{
if(原始值为IList)
{
var templast=(初始值为IList);
var existingList=CurrentProperty.GetValue(OriginalEntity)作为IList;
foreach(模板列表中的变量项)
{
现有列表。添加(项);
}
}
}
}
问题出在哪里?我最近创建了一个扩展方法,它的功能非常类似,只要属性是可写的,就可以处理集合。看起来他的解决方案将数据从一种类型复制到另一种类型。您需要扩展您的答案以获取类型参数,并定义如何确定类型之间哪些属性是等效的。是的,我知道这一点,我理解我的代码的功能,但是您指出的差异与所述问题无关,即我如何处理集合。这是一个可以很好地处理集合的示例,更重要的是,它演示了一个事实,即作为集合的属性不需要与其他类型的属性区别对待。我需要遍历列表中的每个对象,执行另一个递归调用(如果两者都不为null),以再次设置其属性。如果项目在第二个对象(但不是主对象)的列表中,则添加它。我想。