簡體   English   中英

C#反射-將兩個對象合並在一起

[英]C# Reflection - merge two objects together

我需要用對象B的等效屬性(如果不為null)更新對象A的屬性(如果為null)。 我想要可以用於各種對象的代碼。

我有一個版本可以工作,直到其中一個對象包含List類型的屬性,在下面的代碼中空白。 我的主要問題是如何最好地實現這部分代碼。 其次,有一種更好的方法來完成這件事,其三,我知道它永遠不會很快,但是任何加快它的建議都會受到贊賞。

提前致謝。

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

嗨,我修改了Ben Robinsons解決方案,以不覆蓋Collections或list,而是將一個對象的元素添加到發生合並的另一個對象中:

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

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM