微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何深度复制强类型集合的成员

我有两个类XmlPerson和Person,每个类都有公共属性,没有方法也没有任何字段.

我如何将所有属性从Person深度复制到XmlPerson?我不想使用像MiscUtil.Propertycopy或Automapper这样的第三方库.我已经设法复制了作为原始类型和强类型对象的“第一级”属性,但是当它出现时,我不知道.

Person类的结构如下:

public class Person
{
    public string FirstName { get; set; }

    public string Surname { get; set; }

    public decimal? Salary { get; set; }

    public List<AddressDetails> AddressDetails { get; set; }

    public NextOfKin NextOfKin { get; set; }
}

public class NextOfKin
{
    public string FirstName { get; set; }

    public string Surname { get; set; }

    public string ContactNumber { get; set; }

    public List<AddressDetails> AddressDetails { get; set; }
}

public class AddressDetails
{
    public int HouseNumber { get; set; }

    public string StreetName { get; set; }

    public string City { get; set; }
}

谢谢你的帮助.
查尔斯

这是我到目前为止所拥有的:

公共类XmlTestCasetoClassMapper
    {
        内部TTarget MapXmlClasstotargetClass(TSource xmlPerson)
        {
            var targetobject = Activator.CreateInstance();
            var sourceObject = Activator.CreateInstance();

//var xmlClassproperties = xmlPerson.GetType().GetProperties().ToList().OrderBy(x => x.Name);

        var xmlClassproperties = GetProperties(xmlPerson.GetType());

        //var targetClassproperties = targetobject.GetType().GetProperties().ToList().OrderBy(x => x.Name);

        var targetClassproperties = GetProperties(targetobject.GetType());

        PropertyInfo targetClassproperty = null;

        foreach (var xmlProperty in xmlClassproperties)
        {
            if (!xmlProperty.PropertyType.IsClass || xmlProperty.PropertyType.UnderlyingSystemType == typeof(string)
                || xmlProperty.PropertyType.IsPrimitive)
            {
                targetClassproperty = targetClassproperties.ToList().FirstOrDefault(x => x.Name == xmlProperty.Name);

                var propertyValue = xmlProperty.GetValue(xmlPerson,null);

                targetClassproperty.SetValue(targetobject,propertyValue,null);
            }

            else if (xmlProperty.PropertyType.UnderlyingSystemType == typeof(NextOfKin)) //Check subType of the property
            {
                var subPropertyInstance = Activator.CreateInstance(xmlProperty.GetType());
                var subProperties = GetProperties(xmlProperty.GetType());

                subProperties.ForEach(subProperty =>
                {
                    targetClassproperty = targetClassproperties.ToList().FirstOrDefault(x => x.Name == subProperty.Name && x.GetType().IsClass);
                    targetClassproperty.SetValue(subPropertyInstance,xmlProperty.GetValue(this,null),null);
                });
            }

            //else if (xmlProperty.PropertyType.IsGenericType)

            //{

            //        var xmlGenericType = xmlProperty.PropertyType.GetGenericArguments().First();

            //        var xmlGenericTypeProperties = GetProperties(xmlGenericType);

            //        targetClassproperty = targetClassproperties.ToList().FirstOrDefault(x => x.Name == xmlProperty.Name);

            //        var targetGenericType = targetClassproperty.PropertyType.GetGenericArguments().First();

            //        var targetGenericProperties = GetProperties(targetGenericType);

            //        Type targetGenericList = typeof(List<>).MakeGenericType(new Type[] { targetGenericType });

            //        object listInstance = Activator.CreateInstance(targetGenericList);

            //    //foreach (var xmlGenericProperty in xmlGenericTypeProperties)

            //    //{

            //    //    var targetGenericProperty = targetGenericProperties.FirstOrDefault(x => x.Name == xmlGenericProperty.Name);

            //    //    targetGenericProperty.SetValue(targetGenericProperty,xmlGenericProperty.GetValue(xmlGenericType,null);

            //    //}

            //    xmlGenericTypeProperties.ForEach(x =>

            //    {

            //        foreach (var targetGenericProperty in targetGenericProperties)

            //        {

            //            targetGenericProperty.SetValue(targetGenericProperty,targetGenericProperty.GetValue(x,null);

            //        }

            //    });

            //}

            //}

        }
        return targetobject;
    }

    private List<PropertyInfo> GetProperties(Type targettype)
    {
        var properties = new List<PropertyInfo>();

        targettype.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList().ForEach(property =>
        {

            properties.Add(property);

        });

        return properties.OrderBy(x => x.Name).ToList();
    }
}

解决方法

这是一个可能的解决方案.它可能需要根据您的实际课程进行一些调整.

public T Deepcopy<S,T>(S source) where T : new()
{
    var sourceProperties = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public);
    T target = new T();

    foreach (var sourceProperty in sourceProperties)
    {
        var property = typeof(T).GetProperty(sourceProperty.Name);

        if (property.PropertyType.IsPrimitive || 
            property.PropertyType == typeof(string) || 
            (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDeFinition() == typeof(Nullable<>)))
        {
            object value = sourceProperty.GetValue(source);

            property.SetValue(target,value);
        }
        else if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDeFinition() == typeof(List<>))
        {
            var sourceList = (IEnumerable)sourceProperty.GetValue(source);

            if (sourceList != null)
            {
                var deepcopy = this.GetType().getmethod("Deepcopy").MakeGenericmethod(sourceProperty.PropertyType.GenericTypeArguments[0],property.PropertyType.GenericTypeArguments[0]);
                var ctor = property.PropertyType.GetConstructor(Type.EmptyTypes);

                IList targetList = (IList) ctor.Invoke(null);

                foreach (var element in sourceList)
                {
                    targetList.Add(deepcopy.Invoke(this,new object[] { element } ));
                }

                property.SetValue(target,targetList);
            }
        }
        else
        {
            var value = sourceProperty.GetValue(source);

            if (value != null)
            {
                var deepcopy = this.GetType().getmethod("Deepcopy").MakeGenericmethod(sourceProperty.PropertyType,property.PropertyType);

                property.SetValue(target,deepcopy.Invoke(this,new object[] { value }));
            }
        }
    }

    return target;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐